Guida al layout vincolato n.

Come usare il layout vincolato per adattare perfettamente i grafici alla tua figura.

constrained_layout regola automaticamente sottotrame e decorazioni come legende e barre dei colori in modo che si adattino alla finestra della figura pur preservando, nel miglior modo possibile, il layout logico richiesto dall'utente.

constrained_layout è simile a tight_layout , ma utilizza un risolutore di vincoli per determinare la dimensione degli assi che consente loro di adattarsi.

constrained_layout in genere deve essere attivato prima che gli assi vengano aggiunti a una figura. Due modi per farlo sono

Questi sono descritti in dettaglio nelle sezioni seguenti.

Esempio semplice #

In Matplotlib, la posizione degli assi (incluse le sottotrame) è specificata in coordinate di figure normalizzate. Può succedere che le etichette oi titoli degli assi (oa volte anche i ticklabel) escano dall'area della figura e siano quindi tagliati.

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)
Titolo

Per evitare ciò, la posizione degli assi deve essere regolata. Per le sottotrame, questo può essere fatto manualmente regolando i parametri della sottotrama usando Figure.subplots_adjust. Tuttavia, specificando la tua cifra con l' layout="constrained"argomento della parola chiave #, la regolazione # verrà eseguita automaticamente.

fig, ax = plt.subplots(layout="constrained")
example_plot(ax, fontsize=24)
Titolo

Quando hai più sottotrame, spesso vedi etichette di assi diversi che si sovrappongono l'una all'altra.

fig, axs = plt.subplots(2, 2, layout=None)
for ax in axs.flat:
    example_plot(ax)
Titolo, Titolo, Titolo, Titolo

Se si specifica layout="constrained"nella chiamata a plt.subplots , il layout viene vincolato correttamente.

fig, axs = plt.subplots(2, 2, layout="constrained")
for ax in axs.flat:
    example_plot(ax)
Titolo, Titolo, Titolo, Titolo

Barre colore #

Se crei una barra dei colori con Figure.colorbar, devi farle spazio. constrained_layoutlo fa automaticamente. Nota che se lo specifichi use_gridspec=Trueverrà ignorato perché questa opzione è fatta per migliorare il layout tramite tight_layout.

Nota

Per la pcolormeshparola chiave arguments ( pc_kwargs) usiamo un dizionario. Di seguito assegneremo una barra di colore a un numero di assi ciascuno contenente un ScalarMappable; specificando la norma e la mappa dei colori si garantisce che la barra dei colori sia accurata per tutti gli assi.

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)
guida al layout vincolato
<matplotlib.colorbar.Colorbar object at 0x7f2cfafb53c0>

Se specifichi un elenco di assi (o un altro contenitore iterabile) axnell'argomento di colorbar, constrained_layout prenderà spazio dagli assi specificati.

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)
guida al layout vincolato
<matplotlib.colorbar.Colorbar object at 0x7f2cfb6eed70>

Se specifichi un elenco di assi all'interno di una griglia di assi, la barra dei colori ruberà spazio in modo appropriato e lascerà uno spazio vuoto, ma tutte le sottotrame avranno ancora le stesse dimensioni.

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)
guida al layout vincolato
<matplotlib.colorbar.Colorbar object at 0x7f2cdd1a3340>

Sottotitolo #

constrained_layoutpuò anche fare spazio a 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')
Grande sottotitolo
Text(0.5, 0.9895825, 'Big Suptitle')

Leggende #

Le legende possono essere posizionate all'esterno dell'asse principale. Constrained-layout è progettato per gestire questo per Axes.legend(). Tuttavia, constrained-layout nonFigure.legend() gestisce (ancora) le legende create tramite .

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))
guida al layout vincolato
<matplotlib.legend.Legend object at 0x7f2cfb266d70>

Tuttavia, questo ruberà spazio da un layout di sottotrama:

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')
axs[1].legend(loc='center left', bbox_to_anchor=(0.8, 0.5))
guida al layout vincolato
<matplotlib.legend.Legend object at 0x7f2cf99852a0>

Affinché una leggenda o un altro artista non rubi spazio al layout della sottotrama, possiamo leg.set_in_layout(False). Ovviamente questo può significare che la legenda finisce tagliata, ma può essere utile se la trama viene successivamente chiamata con . Nota, tuttavia, che lo stato della legenda dovrà essere nuovamente attivato per far funzionare il file salvato e dobbiamo attivare manualmente un disegno se vogliamo che constrained_layout regoli la dimensione degli assi prima della stampa.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
guida al layout vincolato

Il file salvato è simile a:

../../_images/constrained_layout_1b.png

Un modo migliore per aggirare questo imbarazzo è semplicemente utilizzare il metodo legend fornito da 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
guida al layout vincolato

Il file salvato è simile a:

../../_images/constrained_layout_2b.png

Imbottitura e spaziatura #

Il riempimento tra gli assi è controllato in orizzontale da w_pad e wspace e in verticale da h_pad e hspace . Questi possono essere modificati tramite set. w/h_pad sono lo spazio minimo attorno agli assi in unità di pollici:

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)
guida al layout vincolato

La spaziatura tra le sottotrame è ulteriormente impostata da wspace e hspace . Questi sono specificati come una frazione della dimensione del gruppo di sottotrama nel suo insieme. Se questi valori sono inferiori a w_pad o h_pad , vengono utilizzati invece i pad fissi. Nota di seguito come lo spazio ai bordi non cambia rispetto a quanto sopra, ma lo spazio tra le sottotrame sì.

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)
guida al layout vincolato

Se ci sono più di due colonne, il wspace è condiviso tra loro, quindi qui il wspace è diviso in 2, con un wspace di 0.1 tra ogni colonna:

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)
guida al layout vincolato

GridSpecs ha anche argomenti di parole chiave hspace e wspace opzionali , che verranno utilizzati al posto dei pad impostati da 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)
guida al layout vincolato

Spaziatura con barre colore #

Le barre dei colori sono posizionate a un pad di distanza dal genitore, dove pad è una frazione della larghezza del genitore o dei genitori. La spaziatura alla sottotrama successiva è quindi data da 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)
pad: 0, pad: 0,05, pad: 0,1, pad: 0,2

rcParams #

Ci sono cinque rcParams che possono essere impostati, in uno script o nel matplotlibrc file. Hanno tutti il ​​prefisso figure.constrained_layout:

  • use : se utilizzare constrained_layout. L'impostazione predefinita è False

  • w_pad , h_pad : Imbottitura intorno agli oggetti degli assi. Galleggiante che rappresenta i pollici. L'impostazione predefinita è 3./72. pollici (3 punti)

  • wspace , hspace : spazio tra i gruppi di sottotrame. Float che rappresenta una frazione delle larghezze della sottotrama separate. Il valore predefinito è 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)
Titolo, Titolo, Titolo, Titolo

Utilizzare con GridSpec #

constrained_layout deve essere utilizzato con subplots(), subplot_mosaic()o GridSpec()con add_subplot().

Si noti che in quanto 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)
Titolo, Titolo

Sono possibili layout Gridspec più complicati. Nota qui usiamo le funzioni di convenienza add_gridspece 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)
Titolo, Titolo
Text(0.5, 41.33399999999999, 'x-label')

Si noti che in alto le colonne sinistra e destra non hanno la stessa estensione verticale. Se vogliamo che la parte superiore e inferiore delle due griglie si allineino, devono trovarsi nella stessa griglia specifica. Dobbiamo ingrandire anche questa figura affinché gli assi non collassino a quota 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')
Sovrapposizione Gridspecs, Titolo, Titolo
Text(0.5, 0.993055, 'Overlapping Gridspecs')

Questo esempio utilizza due gridspec per fare in modo che la barra dei colori appartenga solo a un insieme di pcolor. Nota come la colonna di sinistra è più larga delle due colonne di destra per questo motivo. Ovviamente, se si desidera che le sottotrame abbiano le stesse dimensioni, è necessario solo un gridspec. Si noti che lo stesso effetto può essere ottenuto utilizzando 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)
Grafici nidificati utilizzando subgridspec, Title, Title, title, title, title, title
<matplotlib.colorbar.Colorbar object at 0x7f2cdf471c30>

Piuttosto che usare subgridspecs, Matplotlib ora fornisce subfigures che funziona anche con 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')
Grafici nidificati utilizzando sottofigure, titolo, titolo, titolo, titolo, titolo, titolo
Text(0.5, 0.9895825, 'Nested plots using subfigures')

Impostazione manuale delle posizioni degli assi #

Ci possono essere buoni motivi per impostare manualmente una posizione degli assi. Una chiamata manuale a set_positionimposterà gli assi in modo che constrained_layout non abbia più alcun effetto su di essi. (Notare che constrained_layoutlascia ancora lo spazio per gli assi che vengono spostati).

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])
Titolo

Griglie di assi a proporzioni fisse: layout "compresso" #

constrained_layoutopera sulla griglia delle posizioni "originarie" degli assi. Tuttavia, quando gli assi hanno proporzioni fisse, un lato viene solitamente accorciato e lascia ampi spazi nella direzione accorciata. Nel seguito, gli assi sono quadrati, ma la figura è piuttosto ampia quindi c'è uno spazio orizzontale:

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'")
grafici ad aspetto fisso, layout='vincolato'
Text(0.5, 0.98611, "fixed-aspect plots, layout='constrained'")

Un modo ovvio per risolvere questo problema è rendere la dimensione della figura più quadrata, tuttavia, colmare le lacune richiede esattamente tentativi ed errori. Per semplici griglie di assi che possiamo usare layout="compressed"per fare il lavoro per noi:

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'")
grafici ad aspetto fisso, layout='compresso'
Text(0.5, 0.98611, "fixed-aspect plots, layout='compressed'")

Spegnimento manuale constrained_layout#

constrained_layoutdi solito regola le posizioni degli assi su ogni disegno della figura. Se si desidera ottenere la spaziatura fornita da constrained_layoutma non aggiornarla, eseguire il disegno iniziale e quindi chiamare fig.set_layout_engine(None). Ciò è potenzialmente utile per le animazioni in cui le etichette delle tacche possono cambiare lunghezza.

Si noti che constrained_layoutè disattivato per ZOOMgli PAN eventi GUI per i backend che utilizzano la barra degli strumenti. Ciò impedisce agli assi di cambiare posizione durante lo zoom e la panoramica.

Limitazioni #

Funzioni incompatibili #

constrained_layoutfunzionerà con pyplot.subplot, ma solo se il numero di righe e colonne è lo stesso per ogni chiamata. Il motivo è che ogni chiamata a pyplot.subplotcreerà una nuova GridSpecistanza se la geometria non è la stessa, e constrained_layout. Quindi il seguente funziona bene:

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')
Righe omogenee, ncols, Title, Title, Title
Text(0.5, 0.9895825, 'Homogenous nrows, ncols')

ma quanto segue porta a un layout scadente:

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')
Righe miste, colonne, titolo, titolo, titolo
Text(0.5, 0.9895825, 'Mixed nrows, ncols')

Allo stesso modo, subplot2gridfunziona con la stessa limitazione che nrows e ncols non possono modificare affinché il layout abbia un bell'aspetto.

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')
subplot2grid, Titolo, Titolo, Titolo, Titolo
Text(0.5, 0.9895825, 'subplot2grid')

Altri avvertimenti #

  • constrained_layoutconsidera solo le etichette di spunta, le etichette degli assi, i titoli e le legende. Pertanto, altri artisti potrebbero essere ritagliati e potrebbero anche sovrapporsi.

  • Presuppone che lo spazio aggiuntivo necessario per le etichette di spunta, le etichette degli assi e i titoli sia indipendente dalla posizione originale degli assi. Questo è spesso vero, ma ci sono rari casi in cui non lo è.

  • Ci sono piccole differenze nel modo in cui i backend gestiscono i caratteri di rendering, quindi i risultati non saranno identici ai pixel.

  • Un artista che utilizza le coordinate degli assi che si estendono oltre il limite degli assi risulterà in layout insoliti quando vengono aggiunti a un asse. Ciò può essere evitato aggiungendo l'artista direttamente Figureall'utilizzo di add_artist(). Vedere ConnectionPatchper un esempio.

Debug #

Il layout vincolato può fallire in modi alquanto inaspettati. Poiché utilizza un risolutore di vincoli, il risolutore può trovare soluzioni matematicamente corrette, ma che non sono affatto ciò che l'utente desidera. La normale modalità di errore prevede che tutte le dimensioni collassino al valore minimo consentito. Se ciò accade, è per uno dei due motivi:

  1. Non c'era abbastanza spazio per gli elementi che stavi chiedendo di disegnare.

  2. C'è un bug, nel qual caso apri un problema su https://github.com/matplotlib/matplotlib/issues .

Se c'è un bug, segnalalo con un esempio autonomo che non richiede dati esterni o dipendenze (diversi da numpy).

Note sull'algoritmo #

L'algoritmo per il vincolo è relativamente semplice, ma presenta una certa complessità a causa dei modi complessi in cui possiamo disporre una figura.

Il layout in Matplotlib viene eseguito con gridspec tramite la GridSpecclasse. Un gridspec è una divisione logica della figura in righe e colonne, con la larghezza relativa degli assi in quelle righe e colonne impostate da width_ratios e height_ratios .

In constrained_layout, a ogni gridspec viene associato un layoutgrid . Il layoutgrid ha una serie di lefte rightvariabili per ogni colonna bottome topvariabili per ogni riga, e inoltre ha un margine per ciascuno di sinistra, destra, inferiore e superiore. In ogni riga, i margini inferiore/superiore vengono allargati fino a quando tutti i decoratori in quella riga non vengono sistemati. Allo stesso modo per le colonne e i margini sinistro/destro.

Caso semplice: un Asse #

Per un singolo Axes il layout è semplice. C'è un layoutgrid padre per la figura composta da una colonna e una riga, e un layoutgrid figlio per il gridspec che contiene gli assi, sempre costituito da una riga e una colonna. Viene fatto spazio alle "decorazioni" su ogni lato degli assi. Nel codice, ciò è ottenuto dalle voci in do_constrained_layout()come:

gridspec._layoutgrid[0, 0].edit_margin_min('left',
      -bbox.x0 + pos.x0 + w_pad)

dov'è bboxil riquadro di delimitazione stretto degli assi e posla sua posizione. Si noti come i quattro margini racchiudano le decorazioni degli assi.

from matplotlib._layoutgrid import plot_children

fig, ax = plt.subplots(layout="constrained")
example_plot(ax, fontsize=24)
plot_children(fig)
Titolo

Caso semplice: due assi #

Quando sono presenti più assi, i loro layout sono vincolati in modo semplice. In questo esempio l'asse di sinistra ha decorazioni molto più grandi di quello di destra, ma condividono un margine inferiore, che è sufficientemente grande da contenere la xlabel più grande. Lo stesso con il margine superiore condiviso. I margini sinistro e destro non sono condivisi e quindi possono essere diversi.

fig, ax = plt.subplots(1, 2, layout="constrained")
example_plot(ax[0], fontsize=32)
example_plot(ax[1], fontsize=8)
plot_children(fig)
Titolo, Titolo

Due assi e barra dei colori #

Una barra dei colori è semplicemente un altro elemento che espande il margine della cella genitore layoutgrid:

fig, ax = plt.subplots(1, 2, layout="constrained")
im = ax[0].pcolormesh(arr, **pc_kwargs)
fig.colorbar(im, ax=ax[0], shrink=0.6)
im = ax[1].pcolormesh(arr, **pc_kwargs)
plot_children(fig)
guida al layout vincolato

Barra dei colori associata a Gridspec #

Se una barra dei colori appartiene a più di una cella della griglia, crea un margine maggiore per ognuna:

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)
guida al layout vincolato

Assi di dimensioni irregolari #

Esistono due modi per fare in modo che gli assi abbiano una dimensione non uniforme in un layout Gridspec, specificandoli per attraversare righe o colonne Gridspecs o specificando i rapporti di larghezza e altezza.

Il primo metodo è usato qui. Si noti che il centro topei bottommargini non sono influenzati dalla colonna di sinistra. Questa è una decisione consapevole dell'algoritmo e porta al caso in cui i due assi di destra hanno la stessa altezza, ma non è la metà dell'altezza degli assi di sinistra. Ciò è coerente con il modo in cui gridspecfunziona senza layout vincolato.

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)
guida al layout vincolato

Un caso che richiede rifiniture è se i margini non hanno artisti che limitano la loro larghezza. Nel caso seguente, il margine destro per la colonna 0 e il margine sinistro per la colonna 3 non hanno artisti di margine per impostare la loro larghezza, quindi prendiamo la larghezza massima delle larghezze di margine che hanno artisti. Questo fa sì che tutti gli assi abbiano la stessa dimensione:

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()
Titolo

Tempo di esecuzione totale dello script: (0 minuti 18,885 secondi)

Galleria generata da Sphinx-Gallery