Reputation: 431
I am using GridSpec and Subplots in combination with CartoPy to make a custom multi-line title region for generated plots. The code below generates the following figure, please note that for efficiency, I've excluded extraneous lines that format the map, colorbar, and place shapefiles.
The Code
fig = plt.figure(figsize=(14,8))
gs = gridspec.GridSpec(ncols=1, nrows=2, height_ratios=[0.15, 3.00])
gs.update(wspace=0.00, hspace=0.00)
ax1 = fig.add_subplot(gs[0, :])
plt.text(0.00, 0.90, "Left Title Line One", fontsize=15, fontproperties=medprop)
plt.text(0.00, 0.20, "Left Title Line Two", fontsize=15, fontproperties=lgtprop)
plt.text(1.00, 1.00, "Right Title Line One", fontsize=15, ha='right', fontproperties=medprop)
plt.text(1.00, 0.20, "Right Title Line Two", fontsize=15, ha='right', fontproperties=lgtprop)
ax2 = fig.add_subplot(gs[1, :], projection=crs.LambertConformal())
ax2.set_extent(region, crs=crs.LambertConformal())
ax2.set_adjustable('datalim')
im = ax2.pcolormesh(xgrid, ygrid, data.variable.data[0], cmap=cmap, norm=norm, alpha=0.90)
plt.colorbar(im, ax=ax2, pad=0.01, ticks=ticks, aspect=40)
fig.tight_layout()
The Generated Figure
The figure generates successfully, however note that the plot itself does not fill the entire width of the second subplot defined after GridSpec is declared. I've narrowed down the issue to the plot not filling the axes as desired.
Previously, I've tried using ax2 = plt.axes([0.25, 0.05, 0.95, 0.9],projection=crs.LambertConformal())
, however this adds a properly constrained plot (with regards to the axes bounds) over both GridSpec rows and is not confined to the second row. What steps can I take to properly either a) fill the width of the second GridSpec row or b) shorten the width of the first row to match the second?
Upvotes: 0
Views: 204
Reputation: 64453
It's hard to replicate this without all the missing variables you're using. But I suspect gridspec
does exactly what you want in this case, except you then adjust the extent of your second axes (the map) when you add the colorbar.
ax : `~matplotlib.axes.Axes`, list of Axes, optional
One or more parent axes from which space for a new colorbar axes will be
stolen, if *cax* is None. This has no effect if *cax* is set.
If you don't want that, you should probably include the axes for the colorbar (the cax
keyword) when creating the original layout. Or carefully create a new/separate axes that doesn't alter the existing ones from gridspec
.
An easy workaround might be to provide both axes when creating the colorbar, that way both get modified the same way. A side effect is that the colorbar gets aligned with respect to both, which may or may not be what you want aesthetically. For example:
fig = plt.figure(figsize=(10, 5))
gs = mpl.gridspec.GridSpec(ncols=1, nrows=2, height_ratios=[0.25, 3.00])
gs.update(wspace=0.0, hspace=0.0, top=1, bottom=0, left=0, right=1)
ax1 = fig.add_subplot(gs[0, :])
ax1.text(0.00, 0.90, "Left Title Line One", fontsize=15)
ax1.text(0.00, 0.20, "Left Title Line Two", fontsize=15)
ax1.text(1.00, 1.00, "Right Title Line One", fontsize=15, ha='right')
ax1.text(1.00, 0.20, "Right Title Line Two", fontsize=15, ha='right')
ax1.axis("off")
ax2 = fig.add_subplot(gs[1, :], projection=crs.PlateCarree())
im = ax2.imshow(np.random.rand(16, 32), cmap="Blues", extent=[-180, 180, 90, -90])
cb = fig.colorbar(im, ax=[ax1, ax2], pad=0.01, shrink=0.5)
Upvotes: 1