pythonmatplotlibseabornsubplotmatplotlib-gridspec

How to align the left and right spines of subplots in a single column


I am trying to plot two subplots. One of them is a heatmap from seaborn library and other one is line plot from matplotlib. Line plot is showing gasoline prices through the 2022 and heatmap shows the metro line passengers through the months of the 2022. What I am trying to do is showing the relation between gasoline prices and metro passenger counts. Here are my codes:

import matplotlib.pyplot as plt
import seaborn as sns
ddf = pd.DataFrame(total_passengers_by_lines, columns = months, index=lines)
fig, (ax1, ax2) = plt.subplots(2, figsize = (25,10), gridspec_kw={'height_ratios': [1, 3]})
fig.suptitle('The Unleaded Gasoline 95 Prices and Total Passengers Per Lines Through The Year 2022',fontsize=15)
ax1.plot(eu_gas.index, eu_gas['Unleaded Gasoline 95'])
ax1.axes.get_xaxis().set_ticks([])
ax2 = sns.heatmap(ddf, linewidth=1, cmap='Blues', annot= True, robust = True, fmt='d')

The dataframe is something like this:

Jannuary    February    March   April   May     June    July    August  September   October     November    December
272674     296034     449074    738360  1029714 937376  995368  1072082 1069054     1225378     588223     457463

Index is the metro line name (for ex.): F1-TAKSIM-KABATAS FUNICULAR LINE

Here is the result: enter image description here

What I want is to make line plot starts at the same vertical line in heatmap and ends where heatmap ends. So that's how relation can be more clear. But no matter what I tried I couldn't make line plot less wider. I tried to add 'width_ratios':[2, 1] to the gridspec_kw parameter like this:

fig, (ax1, ax2) = plt.subplots(2, figsize = (25,10), gridspec_kw={'height_ratios': [1, 3], 'width_ratios':[2, 1]})

But this method gives me an error:

ValueError: Expected the given number of width ratios to match the number of columns of the grid

Perhaps I need to change the first parameter of the subplots, but how so? There are only 2 plots and 1 column.


Solution

  • The reason for the different widths is because the heatmap has the colorbar. One way to do this is by using gridspec. Create a 2x2 gridspec instead of a 2x1 subplot, and then arrange them as needed. I have used some dummy data and created it. You can adjust the width_ratios to what you need.

    import matplotlib.gridspec
    ## Create 2x2 gridspec and adjust width_ratio
    gs = matplotlib.gridspec.GridSpec(2,2, width_ratios=[100,1], height_ratios=[1,3])
    
    fig = plt.figure(figsize = (25,10))
    ax1 = fig.add_subplot(gs[0,0])  ## As you want to reduce top graph, use position 0,0
    ax2 = fig.add_subplot(gs[1,0])  ## Use second row for heatmap
    ax3 = fig.add_subplot(gs[1,0])  ## Use for colorbar
    
    #fig, (ax1, ax2) = plt.subplots(2, figsize = (25,10), gridspec_kw={'height_ratios': [1, 3]})
    fig.suptitle('The Unleaded Gasoline 95 Prices and Total Passengers Per Lines Through The Year 2022',fontsize=15)
    ax1.plot(eu_gas.index, eu_gas['Unleaded Gasoline 95'])
    ax1.axes.get_xaxis().set_ticks([])
    sns.heatmap(ddf, linewidth=1, cmap='Blues', annot= True, robust = True, fmt='d', ax=ax2, cbar_ax=ax3)
    

    enter image description here