Guide de mise en page contrainte #

Comment utiliser la mise en page contrainte pour ajuster proprement les tracés dans votre figure.

constrained_layout ajuste automatiquement les sous-parcelles et les décorations comme les légendes et les barres de couleurs afin qu'elles tiennent dans la fenêtre de la figure tout en préservant, du mieux qu'elles peuvent, la disposition logique demandée par l'utilisateur.

constrained_layout est similaire à tight_layout , mais utilise un solveur de contraintes pour déterminer la taille des axes qui leur permet de s'adapter.

Constrained_layout doit généralement être activé avant que des axes ne soient ajoutés à une figure. Deux manières de procéder sont

Ceux-ci sont décrits en détail dans les sections suivantes.

Exemple simple #

Dans Matplotlib, l'emplacement des axes (y compris les sous-parcelles) est spécifié en coordonnées de figure normalisées. Il peut arriver que vos libellés ou titres d'axes (ou parfois même des ticklabels) sortent de la zone de la figure, et soient donc tronqués.

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

Pour éviter cela, l'emplacement des axes doit être ajusté. Pour les sous-parcelles, cela peut être fait manuellement en ajustant les paramètres de la sous-parcelle à l'aide de Figure.subplots_adjust. Cependant, spécifier votre chiffre avec l' layout="constrained"argument mot-clé # fera l'ajustement # automatiquement.

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

Lorsque vous avez plusieurs sous-parcelles, vous voyez souvent des étiquettes de différents axes qui se chevauchent.

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

Si vous spécifiez layout="constrained"dans l'appel à plt.subplots , la mise en page est correctement contrainte.

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

Barres de couleur #

Si vous créez une barre de couleurs avec Figure.colorbar, vous devez lui faire de la place. constrained_layoutle fait automatiquement. Notez que si vous le spécifiez use_gridspec=True, il sera ignoré car cette option est faite pour améliorer la mise en page via tight_layout.

Noter

Pour les pcolormesharguments de mot-clé ( pc_kwargs) nous utilisons un dictionnaire. Ci-dessous, nous allons attribuer une barre de couleurs à un certain nombre d'axes contenant chacun un ScalarMappable; spécifier la norme et la palette de couleurs garantit que la barre de couleurs est précise pour tous les axes.

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)
guide de mise en page contrainte
<matplotlib.colorbar.Colorbar object at 0x7f2cfafb53c0>

Si vous spécifiez une liste d'axes (ou un autre conteneur itérable) à l' axargument de colorbar, Constrained_layout prendra de l'espace sur les axes spécifiés.

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)
guide de mise en page contrainte
<matplotlib.colorbar.Colorbar object at 0x7f2cfb6eed70>

Si vous spécifiez une liste d'axes à l'intérieur d'une grille d'axes, la barre de couleurs volera de l'espace de manière appropriée et laissera un espace, mais toutes les sous-parcelles auront toujours la même taille.

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)
guide de mise en page contrainte
<matplotlib.colorbar.Colorbar object at 0x7f2cdd1a3340>

Sous-titre #

constrained_layoutpeut également faire de la place pour 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')
Gros sous-titre
Text(0.5, 0.9895825, 'Big Suptitle')

Légendes #

Les légendes peuvent être placées en dehors de leur axe parent. Constrained-layout est conçu pour gérer cela pour Axes.legend(). Cependant, la mise en page contrainte ne gère pas (encore) les légendes créées via Figure.legend().

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))
guide de mise en page contrainte
<matplotlib.legend.Legend object at 0x7f2cfb266d70>

Cependant, cela volera de l'espace à partir d'une disposition de sous-parcelle :

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))
guide de mise en page contrainte
<matplotlib.legend.Legend object at 0x7f2cf99852a0>

Pour qu'une légende ou un autre artiste ne vole pas d'espace dans la disposition de l'intrigue secondaire, nous pouvons leg.set_in_layout(False). Bien sûr, cela peut signifier que la légende finit par être rognée, mais cela peut être utile si le tracé est ensuite appelé avec . Notez cependant que le statut de la légende devra être à nouveau basculé pour que le fichier enregistré fonctionne, et nous devons déclencher manuellement un dessin si nous voulons que constrained_layout ajuste la taille des axes avant l'impression.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
guide de mise en page contrainte

Le fichier enregistré ressemble à :

../../_images/constrained_layout_1b.png

Une meilleure façon de contourner cette maladresse est d'utiliser simplement la méthode de légende fournie par 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
guide de mise en page contrainte

Le fichier enregistré ressemble à :

../../_images/constrained_layout_2b.png

Remplissage et espacement #

Le remplissage entre les axes est contrôlé horizontalement par w_pad et wspace , et verticalement par h_pad et hspace . Ceux-ci peuvent être modifiés via set. w/h_pad sont l'espace minimum autour des axes en pouces :

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)
guide de mise en page contrainte

L' espacement entre les sous-parcelles est en outre défini par wspace et hspace . Celles-ci sont spécifiées comme une fraction de la taille du groupe de sous-placettes dans son ensemble. Si ces valeurs sont inférieures à w_pad ou h_pad , les pads fixes sont utilisés à la place. Notez ci-dessous comment l'espace sur les bords ne change pas par rapport à ce qui précède, mais l'espace entre les sous-parcelles le fait.

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)
guide de mise en page contrainte

S'il y a plus de deux colonnes, le wspace est partagé entre elles, donc ici le wspace est divisé en 2, avec un wspace de 0.1 entre chaque colonne :

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)
guide de mise en page contrainte

GridSpecs a également des arguments optionnels de mots-clés hspace et wspace , qui seront utilisés à la place des pads définis par 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)
guide de mise en page contrainte

Espacement avec les barres de couleur #

Les barres de couleurs sont placées à une certaine distance de leur parent, où le pad est une fraction de la largeur du ou des parents. L'espacement de la sous-parcelle suivante est alors donné par 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)
pastille : 0, pastille : 0,05, pastille : 0,1, pastille : 0,2

rcParams #

Cinq rcParams peuvent être définis, soit dans un script, soit dans le matplotlibrc fichier. Ils ont tous le préfixe figure.constrained_layout:

  • use : s'il faut utiliser Constrained_layout. La valeur par défaut est False

  • w_pad , h_pad : Rembourrage autour des objets axes. Flotteur représentant les pouces. La valeur par défaut est 3./72. pouces (3 points)

  • wspace , hspace : Espace entre les groupes de sous-parcelles. Flottant représentant une fraction des largeurs de sous-parcelles séparées. La valeur par défaut est 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)
Titre, titre, titre, titre

Utiliser avec GridSpec #

Constrained_layout est destiné à être utilisé avec subplots(), subplot_mosaic()ou GridSpec()avec add_subplot().

A noter que dans ce qui suitlayout="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)
Titre, Titre

Des dispositions de gridspec plus compliquées sont possibles. Notez ici que nous utilisons les fonctions pratiques add_gridspecet 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)
Titre, Titre
Text(0.5, 41.33399999999999, 'x-label')

Notez que dans ce qui précède, les colonnes de gauche et de droite n'ont pas la même étendue verticale. Si nous voulons que le haut et le bas des deux grilles s'alignent, ils doivent être dans la même grille. Nous devons également agrandir cette figure pour que les axes ne s'effondrent pas à une hauteur nulle :

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')
Chevauchement Gridspecs, Titre, Titre
Text(0.5, 0.993055, 'Overlapping Gridspecs')

Cet exemple utilise deux gridspecs pour que la barre de couleurs ne se rapporte qu'à un ensemble de pcolors. Notez que la colonne de gauche est plus large que les deux colonnes de droite à cause de cela. Bien sûr, si vous vouliez que les sous-parcelles aient la même taille, vous n'aviez besoin que d'un seul gridspec. Notez que le même effet peut être obtenu en utilisant 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)
Parcelles imbriquées à l'aide de subgridspec, Titre, Titre, titre, titre, titre, titre
<matplotlib.colorbar.Colorbar object at 0x7f2cdf471c30>

Plutôt que d'utiliser des sous-spécifications de grille, Matplotlib fournit désormais subfigures qui fonctionnent également avecconstrained_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')
Graphiques imbriqués utilisant des sous-figures, Titre, Titre, titre, titre, titre, titre
Text(0.5, 0.9895825, 'Nested plots using subfigures')

Réglage manuel des positions des axes #

Il peut y avoir de bonnes raisons de définir manuellement une position Axes. Un appel manuel à set_positiondéfinira les axes afin que Constrained_layout n'ait plus aucun effet dessus. (Notez qu'il constrained_layoutreste encore de l'espace pour les axes qui sont déplacés).

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

Grilles d'Axes à rapport d'aspect fixe : mise en page "compressée" #

constrained_layoutopère sur la grille des positions "d'origine" des axes. Cependant, lorsque les axes ont des rapports d'aspect fixes, un côté est généralement raccourci et laisse de grands espaces dans la direction raccourcie. Dans ce qui suit, les Axes sont carrés, mais la figure assez large donc il y a un écart 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'")
tracés à aspect fixe, layout='constrained'
Text(0.5, 0.98611, "fixed-aspect plots, layout='constrained'")

Une façon évidente de résoudre ce problème consiste à rendre la taille de la figure plus carrée, cependant, combler les lacunes nécessite exactement des essais et des erreurs. Pour de simples grilles d'axes, nous pouvons utiliser layout="compressed"pour faire le travail pour nous :

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'")
tracés à aspect fixe, layout='compressed'
Text(0.5, 0.98611, "fixed-aspect plots, layout='compressed'")

Désactivation manuelle constrained_layout#

constrained_layoutajuste généralement les positions des axes sur chaque dessin de la figure. Si vous souhaitez obtenir l'espacement fourni par constrained_layoutmais pas le mettre à jour, effectuez le tirage initial, puis appelez fig.set_layout_engine(None). Ceci est potentiellement utile pour les animations où les étiquettes de graduation peuvent changer de longueur.

Notez que constrained_layoutest désactivé pour les événements ZOOMet PAN GUI pour les backends qui utilisent la barre d'outils. Cela empêche les axes de changer de position pendant le zoom et le panoramique.

Limites #

Fonctions incompatibles #

constrained_layoutfonctionnera avec pyplot.subplot, mais uniquement si le nombre de lignes et de colonnes est le même pour chaque appel. La raison en est que chaque appel à pyplot.subplotcréera une nouvelle GridSpecinstance si la géométrie n'est pas la même, et constrained_layout. Donc ce qui suit fonctionne bien :

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')
Nrows homogènes, ncols, Titre, Titre, Titre
Text(0.5, 0.9895825, 'Homogenous nrows, ncols')

mais ce qui suit conduit à une mauvaise mise en page :

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')
Nrows mixtes, ncols, Titre, Titre, Titre
Text(0.5, 0.9895825, 'Mixed nrows, ncols')

De même, subplot2gridfonctionne avec la même limitation que nrows et ncols ne peuvent pas changer pour que la mise en page soit belle.

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

Autres mises en garde #

  • constrained_layoutne prend en compte que les étiquettes de graduation, les étiquettes d'axe, les titres et les légendes. Ainsi, d'autres artistes peuvent être coupés et peuvent également se chevaucher.

  • Il suppose que l'espace supplémentaire nécessaire pour les étiquettes de graduation, les étiquettes d'axe et les titres est indépendant de l'emplacement d'origine des axes. C'est souvent vrai, mais il y a de rares cas où ce n'est pas le cas.

  • Il existe de petites différences dans la façon dont les backends gèrent les polices de rendu, de sorte que les résultats ne seront pas identiques au pixel près.

  • Un artiste utilisant des coordonnées d'axes qui s'étendent au-delà de la limite des axes entraînera des mises en page inhabituelles lorsqu'elles seront ajoutées à un axe. Cela peut être évité en ajoutant l'artiste directement à l' Figureutilisation add_artist(). Voir ConnectionPatchpour un exemple.

Débogage #

La mise en page contrainte peut échouer de manière quelque peu inattendue. Parce qu'il utilise un solveur de contraintes, le solveur peut trouver des solutions mathématiquement correctes, mais qui ne correspondent pas du tout à ce que l'utilisateur souhaite. Le mode de défaillance habituel est que toutes les tailles se réduisent à leur plus petite valeur autorisée. Si cela se produit, c'est pour l'une des deux raisons suivantes :

  1. Il n'y avait pas assez de place pour les éléments que vous demandiez à dessiner.

  2. Il y a un bogue - auquel cas ouvrez un problème sur https://github.com/matplotlib/matplotlib/issues .

S'il y a un bogue, veuillez le signaler avec un exemple autonome qui ne nécessite pas de données ou de dépendances extérieures (autres que numpy).

Remarques sur l'algorithme #

L'algorithme de la contrainte est relativement simple, mais présente une certaine complexité en raison des manières complexes dont nous pouvons mettre en page une figure.

La mise en page dans Matplotlib est effectuée avec gridspecs via la GridSpecclasse. Un gridspec est une division logique de la figure en lignes et colonnes, avec la largeur relative des Axes dans ces lignes et colonnes définies par width_ratios et height_ratios .

Dans Constrained_layout, chaque gridspec obtient une grille de mise en page qui lui est associée. La grille de mise en page a une série de variables leftet rightpour chaque colonne, et des variables bottomet toppour chaque ligne, et en outre, elle a une marge pour chacun des éléments gauche, droite, bas et haut. Dans chaque rangée, les marges inférieures/supérieures sont élargies jusqu'à ce que tous les décorateurs de cette rangée soient pris en compte. De même pour les colonnes et les marges gauche/droite.

Cas simple : un Axe #

Pour un seul Axe, la mise en page est simple. Il existe une grille de mise en page parent pour la figure composée d'une colonne et d'une ligne, et une grille de mise en page enfant pour la grille qui contient les axes, à nouveau composée d'une ligne et d'une colonne. Un espace est fait pour les "décorations" de chaque côté des axes. Dans le code, cela est accompli par les entrées do_constrained_layout()comme :

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

bboxest la boîte englobante serrée des axes, et possa position. Notez comment les quatre marges englobent les décorations des axes.

from matplotlib._layoutgrid import plot_children

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

Cas simple : deux Axes #

Lorsqu'il y a plusieurs axes, leurs dispositions sont liées de manière simple. Dans cet exemple, les axes de gauche ont des décorations beaucoup plus grandes que celles de droite, mais ils partagent une marge inférieure, qui est suffisamment grande pour accueillir le plus grand xlabel. Idem avec la marge supérieure partagée. Les marges gauche et droite ne sont pas partagées et peuvent donc être différentes.

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

Deux axes et barre de couleur #

Une barre de couleurs est simplement un autre élément qui agrandit la marge de la cellule parente de la grille de mise en page :

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)
guide de mise en page contrainte

Colorbar associé à un Gridspec #

Si une barre de couleur appartient à plus d'une cellule de la grille, elle crée une marge plus grande pour chacune :

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)
guide de mise en page contrainte

Haches de taille inégale #

Il existe deux façons de faire en sorte que les axes aient une taille inégale dans une mise en page Gridspec, soit en les spécifiant pour croiser des lignes ou des colonnes Gridspecs, soit en spécifiant des rapports de largeur et de hauteur.

La première méthode est utilisée ici. Notez que le milieu topet bottomles marges ne sont pas affectés par la colonne de gauche. C'est une décision consciente de l'algorithme, et conduit au cas où les deux axes de droite ont la même hauteur, mais ce n'est pas la moitié de la hauteur des axes de gauche. Ceci est cohérent avec le gridspecfonctionnement sans mise en page contrainte.

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)
guide de mise en page contrainte

Un cas qui nécessite un affinement est si les marges n'ont pas d'artistes limitant leur largeur. Dans le cas ci-dessous, la marge de droite pour la colonne 0 et la marge de gauche pour la colonne 3 n'ont pas d'artistes de marge pour définir leur largeur, nous prenons donc la largeur maximale des largeurs de marge qui ont des artistes. Cela fait que tous les axes ont la même taille :

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

Durée totale d'exécution du script : (0 minutes 18,885 secondes)

Galerie générée par Sphinx-Gallery