Observação
Clique aqui para baixar o código de exemplo completo
Guia de layout restrito #
Como usar o layout restrito para ajustar os gráficos à sua figura de maneira limpa.
constraint_layout ajusta automaticamente subtramas e decorações como legendas e barras de cores para que caibam na janela da figura enquanto ainda preservam, da melhor maneira possível, o layout lógico solicitado pelo usuário.
constained_layout é semelhante a tight_layout , mas usa um solucionador de restrição para determinar o tamanho dos eixos que permite que eles se encaixem.
constraind_layout normalmente precisa ser ativado antes que quaisquer eixos sejam adicionados a uma figura. Duas maneiras de fazer isso são
usando o respectivo argumento para
subplots()
oufigure()
, por exemplo:plt.subplots(layout="constrained")
ative-o via rcParams , como:
plt.rcParams['figure.constrained_layout.use'] = True
Esses são descritos em detalhes nas seções a seguir.
Exemplo Simples #
No Matplotlib, a localização dos eixos (incluindo subplots) é especificada em coordenadas de figura normalizadas. Pode acontecer que os rótulos ou títulos de seus eixos (ou às vezes até os rótulos de marcação) saiam da área da figura e sejam cortados.
import matplotlib.pyplot as plt
import matplotlib.colors as mcolors
import matplotlib.gridspec as gridspec
import numpy as np
plt.rcParams['savefig.facecolor'] = "0.8"
plt.rcParams['figure.figsize'] = 4.5, 4.
plt.rcParams['figure.max_open_warning'] = 50
def example_plot(ax, fontsize=12, hide_labels=False):
ax.plot([1, 2])
ax.locator_params(nbins=3)
if hide_labels:
ax.set_xticklabels([])
ax.set_yticklabels([])
else:
ax.set_xlabel('x-label', fontsize=fontsize)
ax.set_ylabel('y-label', fontsize=fontsize)
ax.set_title('Title', fontsize=fontsize)
fig, ax = plt.subplots(layout=None)
example_plot(ax, fontsize=24)
Para evitar isso, a localização dos eixos precisa ser ajustada. Para subparcelas, isso pode ser feito manualmente ajustando os parâmetros da subparcela usando Figure.subplots_adjust
. No entanto, especificar sua figura com o layout="constrained"
argumento de palavra-chave # fará o ajuste # automaticamente.
fig, ax = plt.subplots(layout="constrained")
example_plot(ax, fontsize=24)
Quando você tem várias subtramas, geralmente vê rótulos de diferentes eixos se sobrepondo.
fig, axs = plt.subplots(2, 2, layout=None)
for ax in axs.flat:
example_plot(ax)
Especificar layout="constrained"
na chamada para plt.subplots
faz com que o layout seja devidamente restrito.
fig, axs = plt.subplots(2, 2, layout="constrained")
for ax in axs.flat:
example_plot(ax)
Barras de cores #
Se você criar uma barra de cores com Figure.colorbar
, precisará abrir espaço para ela. constrained_layout
faz isso automaticamente. Observe que se você especificar use_gridspec=True
será ignorado porque esta opção é feita para melhorar o layout via
tight_layout
.
Observação
Para os pcolormesh
argumentos de palavra-chave ( pc_kwargs
), usamos um dicionário. A seguir, atribuiremos uma barra de cores a vários eixos, cada um contendo um ScalarMappable
; especificar a norma e o mapa de cores garante que a barra de cores seja precisa para todos os eixos.
arr = np.arange(100).reshape((10, 10))
norm = mcolors.Normalize(vmin=0., vmax=100.)
# see note above: this makes all pcolormesh calls consistent:
pc_kwargs = {'rasterized': True, 'cmap': 'viridis', 'norm': norm}
fig, ax = plt.subplots(figsize=(4, 4), layout="constrained")
im = ax.pcolormesh(arr, **pc_kwargs)
fig.colorbar(im, ax=ax, shrink=0.6)
<matplotlib.colorbar.Colorbar object at 0x7f2cfafb53c0>
Se você especificar uma lista de eixos (ou outro contêiner iterável) para o
ax
argumento de colorbar
, o constraintd_layout ocupará espaço dos eixos especificados.
fig, axs = plt.subplots(2, 2, figsize=(4, 4), layout="constrained")
for ax in axs.flat:
im = ax.pcolormesh(arr, **pc_kwargs)
fig.colorbar(im, ax=axs, shrink=0.6)
<matplotlib.colorbar.Colorbar object at 0x7f2cfb6eed70>
Se você especificar uma lista de eixos de dentro de uma grade de eixos, a barra de cores roubará espaço apropriadamente e deixará uma lacuna, mas todos os subplots ainda terão o mesmo tamanho.
fig, axs = plt.subplots(3, 3, figsize=(4, 4), layout="constrained")
for ax in axs.flat:
im = ax.pcolormesh(arr, **pc_kwargs)
fig.colorbar(im, ax=axs[1:, ][:, 1], shrink=0.8)
fig.colorbar(im, ax=axs[:, -1], shrink=0.6)
<matplotlib.colorbar.Colorbar object at 0x7f2cdd1a3340>
Legenda #
constrained_layout
também pode abrir espaço para suptitle
.
fig, axs = plt.subplots(2, 2, figsize=(4, 4), layout="constrained")
for ax in axs.flat:
im = ax.pcolormesh(arr, **pc_kwargs)
fig.colorbar(im, ax=axs, shrink=0.6)
fig.suptitle('Big Suptitle')
Text(0.5, 0.9895825, 'Big Suptitle')
Legendas #
As legendas podem ser colocadas fora de seu eixo pai. O layout restrito foi projetado para lidar com isso para Axes.legend()
. No entanto, o layout restrito não lida com as legendas criadas por meio de
Figure.legend()
(ainda).
fig, ax = plt.subplots(layout="constrained")
ax.plot(np.arange(10), label='This is a plot')
ax.legend(loc='center left', bbox_to_anchor=(0.8, 0.5))
<matplotlib.legend.Legend object at 0x7f2cfb266d70>
No entanto, isso roubará espaço de um layout de subtrama:
<matplotlib.legend.Legend object at 0x7f2cf99852a0>
Para que uma lenda ou outro artista não roube espaço do layout da subtrama, podemos leg.set_in_layout(False)
. Claro que isso pode significar que a legenda acaba cortada, mas pode ser útil se o gráfico for chamado posteriormente com . Observe, no entanto, que o status da legenda terá que ser alternado novamente para fazer o arquivo salvo funcionar, e devemos acionar manualmente um desenho se quisermos que o constraintd_layout ajuste o tamanho dos eixos antes de imprimir.fig.savefig('outname.png', bbox_inches='tight')
get_in_layout
fig, axs = plt.subplots(1, 2, figsize=(4, 2), layout="constrained")
axs[0].plot(np.arange(10))
axs[1].plot(np.arange(10), label='This is a plot')
leg = axs[1].legend(loc='center left', bbox_to_anchor=(0.8, 0.5))
leg.set_in_layout(False)
# trigger a draw so that constrained_layout is executed once
# before we turn it off when printing....
fig.canvas.draw()
# we want the legend included in the bbox_inches='tight' calcs.
leg.set_in_layout(True)
# we don't want the layout to change at this point.
fig.set_layout_engine(None)
try:
fig.savefig('../../doc/_static/constrained_layout_1b.png',
bbox_inches='tight', dpi=100)
except FileNotFoundError:
# this allows the script to keep going if run interactively and
# the directory above doesn't exist
pass
O arquivo salvo se parece com:
Uma maneira melhor de contornar esse constrangimento é simplesmente usar o método de legenda fornecido por Figure.legend
:
fig, axs = plt.subplots(1, 2, figsize=(4, 2), layout="constrained")
axs[0].plot(np.arange(10))
lines = axs[1].plot(np.arange(10), label='This is a plot')
labels = [l.get_label() for l in lines]
leg = fig.legend(lines, labels, loc='center left',
bbox_to_anchor=(0.8, 0.5), bbox_transform=axs[1].transAxes)
try:
fig.savefig('../../doc/_static/constrained_layout_2b.png',
bbox_inches='tight', dpi=100)
except FileNotFoundError:
# this allows the script to keep going if run interactively and
# the directory above doesn't exist
pass
O arquivo salvo se parece com:
Preenchimento e Espaçamento #
O preenchimento entre os eixos é controlado na horizontal por w_pad e
wspace , e na vertical por h_pad e hspace . Estes podem ser editados via set
. w/h_pad são o espaço mínimo ao redor dos eixos em unidades de polegadas:
fig, axs = plt.subplots(2, 2, layout="constrained")
for ax in axs.flat:
example_plot(ax, hide_labels=True)
fig.get_layout_engine().set(w_pad=4 / 72, h_pad=4 / 72, hspace=0,
wspace=0)
O espaçamento entre os subplots é ainda definido por wspace e hspace . Estes são especificados como uma fração do tamanho do grupo de subparcelas como um todo. Se esses valores forem menores que w_pad ou h_pad , os pads fixos serão usados. Observe abaixo como o espaço nas bordas não muda em relação ao anterior, mas o espaço entre as subparcelas sim.
fig, axs = plt.subplots(2, 2, layout="constrained")
for ax in axs.flat:
example_plot(ax, hide_labels=True)
fig.get_layout_engine().set(w_pad=4 / 72, h_pad=4 / 72, hspace=0.2,
wspace=0.2)
Se houver mais de duas colunas, o wspace é compartilhado entre elas, então aqui o wspace é dividido em 2, com um wspace de 0,1 entre cada coluna:
fig, axs = plt.subplots(2, 3, layout="constrained")
for ax in axs.flat:
example_plot(ax, hide_labels=True)
fig.get_layout_engine().set(w_pad=4 / 72, h_pad=4 / 72, hspace=0.2,
wspace=0.2)
GridSpecs também têm argumentos de palavra-chave hspace e wspace opcionais , que serão usados em vez dos pads definidos por constrained_layout
:
fig, axs = plt.subplots(2, 2, layout="constrained",
gridspec_kw={'wspace': 0.3, 'hspace': 0.2})
for ax in axs.flat:
example_plot(ax, hide_labels=True)
# this has no effect because the space set in the gridspec trumps the
# space set in constrained_layout.
fig.get_layout_engine().set(w_pad=4 / 72, h_pad=4 / 72, hspace=0.0,
wspace=0.0)
Espaçamento com barras de cores #
As barras de cores são colocadas a um pad de distância de seu pai, onde o pad é uma fração da largura do(s) pai(s). O espaçamento para a próxima subtrama é dado por w/hspace .
fig, axs = plt.subplots(2, 2, layout="constrained")
pads = [0, 0.05, 0.1, 0.2]
for pad, ax in zip(pads, axs.flat):
pc = ax.pcolormesh(arr, **pc_kwargs)
fig.colorbar(pc, ax=ax, shrink=0.6, pad=pad)
ax.set_xticklabels([])
ax.set_yticklabels([])
ax.set_title(f'pad: {pad}')
fig.get_layout_engine().set(w_pad=2 / 72, h_pad=2 / 72, hspace=0.2,
wspace=0.2)
rcParams #
Existem cinco rcParams
que podem ser definidos, seja em um script ou no matplotlibrc
arquivo. Todos eles têm o prefixo figure.constrained_layout
:
use : se deve usar o constraintd_layout. O padrão é falso
w_pad , h_pad : Preenchimento em torno de objetos de eixos. Float representando polegadas. O padrão é 3./72. polegadas (3 pontos)
wspace , hspace : Espaço entre grupos de subtrama. Float representando uma fração das larguras da subparcela sendo separadas. O padrão é 0,02.
plt.rcParams['figure.constrained_layout.use'] = True
fig, axs = plt.subplots(2, 2, figsize=(3, 3))
for ax in axs.flat:
example_plot(ax)
Use com GridSpec #
constraintd_layout deve ser usado com subplots()
,
subplot_mosaic()
ou
GridSpec()
com
add_subplot()
.
Observe que no que seguelayout="constrained"
plt.rcParams['figure.constrained_layout.use'] = False
fig = plt.figure(layout="constrained")
gs1 = gridspec.GridSpec(2, 1, figure=fig)
ax1 = fig.add_subplot(gs1[0])
ax2 = fig.add_subplot(gs1[1])
example_plot(ax1)
example_plot(ax2)
Layouts gridspec mais complicados são possíveis. Observe que aqui usamos as funções de conveniência add_gridspec
e
subgridspec
.
fig = plt.figure(layout="constrained")
gs0 = fig.add_gridspec(1, 2)
gs1 = gs0[0].subgridspec(2, 1)
ax1 = fig.add_subplot(gs1[0])
ax2 = fig.add_subplot(gs1[1])
example_plot(ax1)
example_plot(ax2)
gs2 = gs0[1].subgridspec(3, 1)
for ss in gs2:
ax = fig.add_subplot(ss)
example_plot(ax)
ax.set_title("")
ax.set_xlabel("")
ax.set_xlabel("x-label", fontsize=12)
Text(0.5, 41.33399999999999, 'x-label')
Observe que acima as colunas esquerda e direita não têm a mesma extensão vertical. Se quisermos que a parte superior e inferior das duas grades se alinhem, elas precisam estar no mesmo gridspec. Precisamos aumentar essa figura também para que os eixos não caiam para a altura zero:
fig = plt.figure(figsize=(4, 6), layout="constrained")
gs0 = fig.add_gridspec(6, 2)
ax1 = fig.add_subplot(gs0[:3, 0])
ax2 = fig.add_subplot(gs0[3:, 0])
example_plot(ax1)
example_plot(ax2)
ax = fig.add_subplot(gs0[0:2, 1])
example_plot(ax, hide_labels=True)
ax = fig.add_subplot(gs0[2:4, 1])
example_plot(ax, hide_labels=True)
ax = fig.add_subplot(gs0[4:, 1])
example_plot(ax, hide_labels=True)
fig.suptitle('Overlapping Gridspecs')
Text(0.5, 0.993055, 'Overlapping Gridspecs')
Este exemplo usa duas especificações de grade para que a barra de cores pertença apenas a um conjunto de pcolors. Observe como a coluna da esquerda é mais larga do que as duas colunas da direita por causa disso. Claro, se você quiser que os subplots tenham o mesmo tamanho, você só precisa de um gridspec. Observe que o mesmo efeito pode ser obtido usando subfigures
.
fig = plt.figure(layout="constrained")
gs0 = fig.add_gridspec(1, 2, figure=fig, width_ratios=[1, 2])
gs_left = gs0[0].subgridspec(2, 1)
gs_right = gs0[1].subgridspec(2, 2)
for gs in gs_left:
ax = fig.add_subplot(gs)
example_plot(ax)
axs = []
for gs in gs_right:
ax = fig.add_subplot(gs)
pcm = ax.pcolormesh(arr, **pc_kwargs)
ax.set_xlabel('x-label')
ax.set_ylabel('y-label')
ax.set_title('title')
axs += [ax]
fig.suptitle('Nested plots using subgridspec')
fig.colorbar(pcm, ax=axs)
<matplotlib.colorbar.Colorbar object at 0x7f2cdf471c30>
Em vez de usar subgridspecs, o Matplotlib agora fornece subfigures
que também funciona com constrained_layout
:
fig = plt.figure(layout="constrained")
sfigs = fig.subfigures(1, 2, width_ratios=[1, 2])
axs_left = sfigs[0].subplots(2, 1)
for ax in axs_left.flat:
example_plot(ax)
axs_right = sfigs[1].subplots(2, 2)
for ax in axs_right.flat:
pcm = ax.pcolormesh(arr, **pc_kwargs)
ax.set_xlabel('x-label')
ax.set_ylabel('y-label')
ax.set_title('title')
fig.colorbar(pcm, ax=axs_right)
fig.suptitle('Nested plots using subfigures')
Text(0.5, 0.9895825, 'Nested plots using subfigures')
Definir manualmente as posições dos eixos #
Pode haver boas razões para definir manualmente uma posição dos eixos. Uma chamada manual para set_position
definirá os eixos de modo que o constraint_layout não tenha mais efeito sobre ele. (Observe que constrained_layout
ainda sobra espaço para os eixos que são movidos).
fig, axs = plt.subplots(1, 2, layout="constrained")
example_plot(axs[0], fontsize=12)
axs[1].set_position([0.2, 0.2, 0.4, 0.4])
Grades de eixos de proporção fixa: layout "comprimido" #
constrained_layout
opera na grade de posições "originais" para os eixos. No entanto, quando os eixos têm proporções fixas, um lado geralmente é encurtado e deixa grandes lacunas na direção encurtada. A seguir, os eixos são quadrados, mas a figura é bastante larga, então há uma lacuna horizontal:
fig, axs = plt.subplots(2, 2, figsize=(5, 3),
sharex=True, sharey=True, layout="constrained")
for ax in axs.flat:
ax.imshow(arr)
fig.suptitle("fixed-aspect plots, layout='constrained'")
Text(0.5, 0.98611, "fixed-aspect plots, layout='constrained'")
Uma maneira óbvia de corrigir isso é tornar o tamanho da figura mais quadrado; no entanto, fechar as lacunas com precisão requer tentativa e erro. Para grades simples de eixos, podemos usar layout="compressed"
para fazer o trabalho para nós:
fig, axs = plt.subplots(2, 2, figsize=(5, 3),
sharex=True, sharey=True, layout='compressed')
for ax in axs.flat:
ax.imshow(arr)
fig.suptitle("fixed-aspect plots, layout='compressed'")
Text(0.5, 0.98611, "fixed-aspect plots, layout='compressed'")
Desligando manualmente constrained_layout
#
constrained_layout
geralmente ajusta as posições dos eixos em cada desenho da figura. Se você deseja obter o espaçamento fornecido por,
constrained_layout
mas não atualizá-lo, faça o desenho inicial e chame fig.set_layout_engine(None)
. Isso é potencialmente útil para animações em que os rótulos dos marcadores podem mudar de tamanho.
Observe que constrained_layout
está desativado para ZOOM
e PAN
eventos GUI para os back-ends que usam a barra de ferramentas. Isso evita que os eixos mudem de posição durante o zoom e a panorâmica.
Limitações #
Funções incompatíveis #
constrained_layout
funcionará com pyplot.subplot
, mas apenas se o número de linhas e colunas for o mesmo para cada chamada. O motivo é que cada chamada para pyplot.subplot
criará uma nova
GridSpec
instância se a geometria não for a mesma e
constrained_layout
. Então o seguinte funciona bem:
fig = plt.figure(layout="constrained")
ax1 = plt.subplot(2, 2, 1)
ax2 = plt.subplot(2, 2, 3)
# third axes that spans both rows in second column:
ax3 = plt.subplot(2, 2, (2, 4))
example_plot(ax1)
example_plot(ax2)
example_plot(ax3)
plt.suptitle('Homogenous nrows, ncols')
Text(0.5, 0.9895825, 'Homogenous nrows, ncols')
mas o seguinte leva a um layout ruim:
fig = plt.figure(layout="constrained")
ax1 = plt.subplot(2, 2, 1)
ax2 = plt.subplot(2, 2, 3)
ax3 = plt.subplot(1, 2, 2)
example_plot(ax1)
example_plot(ax2)
example_plot(ax3)
plt.suptitle('Mixed nrows, ncols')
Text(0.5, 0.9895825, 'Mixed nrows, ncols')
Da mesma forma,
subplot2grid
funciona com a mesma limitação de que nrows e ncols não podem mudar para que o layout tenha uma boa aparência.
fig = plt.figure(layout="constrained")
ax1 = plt.subplot2grid((3, 3), (0, 0))
ax2 = plt.subplot2grid((3, 3), (0, 1), colspan=2)
ax3 = plt.subplot2grid((3, 3), (1, 0), colspan=2, rowspan=2)
ax4 = plt.subplot2grid((3, 3), (1, 2), rowspan=2)
example_plot(ax1)
example_plot(ax2)
example_plot(ax3)
example_plot(ax4)
fig.suptitle('subplot2grid')
Text(0.5, 0.9895825, 'subplot2grid')
Outras advertências #
constrained_layout
considera apenas marcadores, rótulos de eixo, títulos e legendas. Assim, outros artistas podem ser recortados e também podem se sobrepor.Ele assume que o espaço extra necessário para marcadores, rótulos de eixo e títulos é independente da localização original dos eixos. Isso geralmente é verdade, mas há casos raros em que não é.
Há pequenas diferenças em como os back-ends lidam com as fontes de renderização, portanto, os resultados não serão idênticos aos pixels.
Um artista usando coordenadas de eixos que se estendem além dos limites dos eixos resultará em layouts incomuns quando adicionados a um eixo. Isso pode ser evitado adicionando o artista diretamente ao
Figure
arquivoadd_artist()
. VejaConnectionPatch
um exemplo.
Depuração #
O layout restrito pode falhar de maneiras um tanto inesperadas. Como ele usa um solucionador de restrições, o solucionador pode encontrar soluções matematicamente corretas, mas que não são o que o usuário deseja. O modo de falha usual é para todos os tamanhos entrarem em colapso em seu menor valor permitido. Se isso acontecer, é por um dos dois motivos:
Não havia espaço suficiente para os elementos que você desejava desenhar.
Há um bug - nesse caso, abra um problema em https://github.com/matplotlib/matplotlib/issues .
Se houver um bug, informe com um exemplo independente que não exija dados externos ou dependências (além de numpy).
Notas sobre o algoritmo #
O algoritmo para a restrição é relativamente simples, mas tem alguma complexidade devido às formas complexas com que podemos dispor uma figura.
O layout no Matplotlib é executado com gridspecs por meio da GridSpec
classe. Um gridspec é uma divisão lógica da figura em linhas e colunas, com a largura relativa dos eixos nessas linhas e colunas definidas por width_ratios e height_ratios .
Em constained_layout, cada gridspec obtém um layoutgrid associado a ele. O layoutgrid tem uma série de left
e right
variáveis para cada coluna, bottom
e top
variáveis para cada linha, e ainda tem uma margem para cada esquerda, direita, inferior e superior. Em cada linha, as margens inferior/superior são alargadas até que todos os decoradores dessa linha sejam acomodados. Da mesma forma para colunas e margens esquerda/direita.
Caso simples: um Axes #
Para um único eixo, o layout é direto. Existe um layoutgrid pai para a figura que consiste em uma coluna e linha, e um layoutgrid filho para o gridspec que contém os eixos, novamente consistindo em uma linha e coluna. Espaço é feito para as "decorações" em cada lado dos eixos. No código, isso é feito pelas entradas
do_constrained_layout()
como:
gridspec._layoutgrid[0, 0].edit_margin_min('left',
-bbox.x0 + pos.x0 + w_pad)
onde bbox
é a caixa delimitadora apertada dos eixos e pos
sua posição. Observe como as quatro margens abrangem as decorações dos eixos.
from matplotlib._layoutgrid import plot_children
fig, ax = plt.subplots(layout="constrained")
example_plot(ax, fontsize=24)
plot_children(fig)
Caso simples: dois eixos #
Quando há vários eixos, eles têm seus layouts vinculados de maneira simples. Neste exemplo, o eixo esquerdo tem decorações muito maiores do que o direito, mas eles compartilham uma margem inferior, que é grande o suficiente para acomodar o xlabel maior. O mesmo com a margem superior compartilhada. As margens esquerda e direita não são compartilhadas e, portanto, podem ser diferentes.
fig, ax = plt.subplots(1, 2, layout="constrained")
example_plot(ax[0], fontsize=32)
example_plot(ax[1], fontsize=8)
plot_children(fig)
Dois eixos e colorbar #
Uma barra de cores é simplesmente outro item que expande a margem da célula pai do layoutgrid:
Barra de cores associada a um Gridspec #
Se uma barra de cores pertencer a mais de uma célula da grade, ela cria uma margem maior para cada uma:
fig, axs = plt.subplots(2, 2, layout="constrained")
for ax in axs.flat:
im = ax.pcolormesh(arr, **pc_kwargs)
fig.colorbar(im, ax=axs, shrink=0.6)
plot_children(fig)
Eixos de tamanho irregular #
Existem duas maneiras de fazer com que os eixos tenham um tamanho irregular em um layout Gridspec, especificando-os para cruzar linhas ou colunas Gridspecs ou especificando proporções de largura e altura.
O primeiro método é usado aqui. Observe que o meio top
e
as bottom
margens não são afetados pela coluna da esquerda. Esta é uma decisão consciente do algoritmo e leva ao caso em que os dois eixos da direita têm a mesma altura, mas não é 1/2 da altura dos eixos da esquerda. Isso é consistente com a forma como gridspec
funciona sem layout restrito.
fig = plt.figure(layout="constrained")
gs = gridspec.GridSpec(2, 2, figure=fig)
ax = fig.add_subplot(gs[:, 0])
im = ax.pcolormesh(arr, **pc_kwargs)
ax = fig.add_subplot(gs[0, 1])
im = ax.pcolormesh(arr, **pc_kwargs)
ax = fig.add_subplot(gs[1, 1])
im = ax.pcolormesh(arr, **pc_kwargs)
plot_children(fig)
Um caso que requer sutileza é se as margens não tiverem nenhum artista restringindo sua largura. No caso abaixo, a margem direita da coluna 0 e a margem esquerda da coluna 3 não possuem artistas de margem para definir sua largura, então pegamos a largura máxima das larguras de margem que possuem artistas. Isso faz com que todos os eixos tenham o mesmo tamanho:
fig = plt.figure(layout="constrained")
gs = fig.add_gridspec(2, 4)
ax00 = fig.add_subplot(gs[0, 0:2])
ax01 = fig.add_subplot(gs[0, 2:])
ax10 = fig.add_subplot(gs[1, 1:3])
example_plot(ax10, fontsize=14)
plot_children(fig)
plt.show()
Tempo total de execução do script: ( 0 minutos 18,885 segundos)