Using gridspec with constrained_layout

Question:

I would like to create the following plot with Python in PyCharm:

GridSpec

I am using the following code:

import matplotlib.pyplot as plt
from matplotlib.gridspec import GridSpec


def format_axes(fig):
    for i, ax in enumerate(fig.axes):
        ax.text(0.5, 0.5, "ax%d" % (i+1), va="center", ha="center")
        ax.tick_params(labelbottom=False, labelleft=False)

fig = plt.figure(constrained_layout=True)

gs = GridSpec(3, 3, figure=fig)
ax1 = fig.add_subplot(gs[:2, 0])
ax2 = fig.add_subplot(gs[:2, 1:])
ax3 = fig.add_subplot(gs[-1, 1:])

fig.suptitle("GridSpec")
format_axes(fig)

plt.show()

However I’ve got the following warning:

UserWarning: constrained_layout not applied. At least one axes collapsed to zero width or height.

Does anybody know how to get rid of this warning?

Asked By: ab3001

||

Answers:

constrained_layout is a bit buggy when there are columns with margins that have no edge on a subplot. eg your ax2 and ax3 encompass two grid columns, and there is no axes that defines the boundary between the two. This is a known bug, and would be preferable if it didn’t exist, but…

However, in this case, it is preferable to use width_ratios and height_ratios and use the 2×2 layout you actually want. A modern way to do this is to use subplot_mosaic though you can easily adapt your method as well

import matplotlib.pyplot as plt
from matplotlib.gridspec import GridSpec


def format_axes(axs):
    for k in axs:
        axs[k].text(0.5, 0.5, f"ax: {k}", va="center", ha="center")
        axs[k].tick_params(labelbottom=False, labelleft=False)


fig, axs = plt.subplot_mosaic([["A", "B"], [".", "C"]], constrained_layout=True,
                              gridspec_kw={'width_ratios':[1, 2],
                              'height_ratios':[2, 1]})
fig.suptitle("subplot_mosaic")
format_axes(axs)

enter image description here

Using your old-style method gets identical results, plus or minus the labelling:

fig = plt.figure(constrained_layout=True)
gs = fig.add_gridspec(2, 2, width_ratios=[1, 2], height_ratios=[2, 1])
ax1 = fig.add_subplot(gs[0, 0])
ax2 = fig.add_subplot(gs[0, 1])
ax3 = fig.add_subplot(gs[1, 1])
Answered By: Jody Klymak
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.