Question: I need to combine imshow and regular line plots to create a figure. Unfortunately, the imshow plot area is smaller than the regular line plots, leading to something that looks like this: fig = plt.figure(figsize=(25, 9)) map_subplots = [ plt.subplot(2, 5, 1, projection=ccrs.PlateCarree()), plt.subplot(2, 5, 3, projection=ccrs.PlateCarree()), plt.subplot(2, 5, 6, projection=ccrs.PlateCarree()), plt.subplot(2, 5, 8, projection=ccrs.PlateCarree()) ] for i, ax in enumerate(map_subplots): ax.set_title(titles[i]) ax.coastlines(linewidth=0.5) ax.imshow(eofs[i], extent=[0, 360, -90, 90], transform=ccrs.PlateCarree(), cmap='RdBu_r', origin='lower', vmin=-0.01, vmax=0.01) ts_subplots = [ plt.subplot(2, 5, 2), plt.subplot(2, 5, 4), plt.subplot(2, 5, 7), plt.subplot(2, 5, 9) ] for i, ax in enumerate(ts_subplots): ax.plot(pcs.time, pcs.sel(pc=i)) ax.set_ylim(-100, 100) if True: # remove yticks ax.set_yticks([]) ax.set_xticks(pd.date_range("2013-01-01", "2016-01-01", freq='6MS')) ax.set_xticklabels(["2013", "Jul", "2014", "Jul", "2015", "Jul", "2016"])   I've got a hacky workaround with gridspec, that spreads the imshow plots over multiple subplots, so that it forces them to be bigger: # Create a figure fig = plt.figure(figsize=(15, 9)) # Define a gridspec with custom widths and heights for each subplot hr = 0.6 wr = 0.7 gs = gridspec.GridSpec(6, 5, width_ratios=[1, wr, 1, wr, 1], height_ratios=[hr, 1, hr, hr, 1, hr]) # Map subplots map_subplots = [ plt.subplot(gs[:3, 0], projection=ccrs.PlateCarree()), plt.subplot(gs[:3, 2], projection=ccrs.PlateCarree()), plt.subplot(gs[3:, 0], projection=ccrs.PlateCarree()), plt.subplot(gs[3:, 2], projection=ccrs.PlateCarree()) ] # Plot the map subplots for i, ax in enumerate(map_subplots): ax.set_title(titles[i]) ax.coastlines(linewidth=0.5) ax.imshow(eofs[i], extent=[0, 360, -90, 90], transform=ccrs.PlateCarree(), cmap='RdBu_r', origin='lower', vmin=-0.01, vmax=0.01) # Time series subplots ts_subplots = [ plt.subplot(gs[1, 1]), plt.subplot(gs[1, 3]), plt.subplot(gs[4, 1]), plt.subplot(gs[4, 3]) ] # Plot the time series subplots for i, ax in enumerate(ts_subplots): ax.plot(pcs.time, pcs.sel(pc=i)) ax.set_ylim(-100, 100) if True: # remove yticks ax.set_yticks([]) ax.set_xticks(pd.date_range("2013-01-01", "2016-01-01", freq='6MS')) ax.set_xticklabels(["2013", "Jul", "2014", "Jul", "2015", "Jul", "2016"]) # fig.text(0.04, 0.5, 'PC value (arb. units)', va='center', rotation='vertical', fontsize=12) plt.subplots_adjust(wspace=0.1, hspace=0) plt.tight_layout() plt.show()   This is very close to working, but there's a huge gap between the two rows, which I can't get rid of, no matter how negative a subplots_adjust parameter I supply. Any ideas on how to fix this?

Answer: This is what compressed layout is meant to handle (https://matplotlib.org/stable/users/explain/axes/constrainedlayout_guide.html#grids-of-fixed-aspect-ratio-axes-compressed-layout) Note that there is still blank space, but it is above and below the plots instead of between them. One fix for that is to either adjust the size of the figure manually, or to use bbox_inches='tight' when you save the figure. import matplotlib.pyplot as plt import numpy as np fig, axs = plt.subplots(2, 2, layout='compressed') axs[0, 0].imshow(np.random.rand(100, 400)) axs[0, 1].plot(np.random.randn(500)) axs[1, 0].imshow(np.random.rand(100, 400)) axs[1, 1].plot(np.random.randn(500)) plt.show()