Noter
Cliquez ici pour télécharger l'exemple de code complet
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
en utilisant l'argument respectif de
subplots()
oufigure()
, par exemple :plt.subplots(layout="constrained")
activez-le via rcParams , comme:
plt.rcParams['figure.constrained_layout.use'] = True
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)
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)
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)
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)
Barres de couleur #
Si vous créez une barre de couleurs avec Figure.colorbar
, vous devez lui faire de la place. constrained_layout
le 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 pcolormesh
arguments 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)
<matplotlib.colorbar.Colorbar object at 0x7f2cfafb53c0>
Si vous spécifiez une liste d'axes (ou un autre conteneur itérable) à l'
ax
argument 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)
<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)
<matplotlib.colorbar.Colorbar object at 0x7f2cdd1a3340>
Sous-titre #
constrained_layout
peut é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')
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))
<matplotlib.legend.Legend object at 0x7f2cfb266d70>
Cependant, cela volera de l'espace à partir d'une disposition de sous-parcelle :
<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
Le fichier enregistré ressemble à :
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
Le fichier enregistré ressemble à :
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)
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)
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)
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)
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)
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)
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)
Des dispositions de gridspec plus compliquées sont possibles. Notez ici que nous utilisons les fonctions pratiques add_gridspec
et
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')
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')
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)
<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')
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_position
définira les axes afin que Constrained_layout n'ait plus aucun effet dessus. (Notez qu'il constrained_layout
reste 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])
Grilles d'Axes à rapport d'aspect fixe : mise en page "compressée" #
constrained_layout
opè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'")
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'")
Text(0.5, 0.98611, "fixed-aspect plots, layout='compressed'")
Désactivation manuelle constrained_layout
#
constrained_layout
ajuste généralement les positions des axes sur chaque dessin de la figure. Si vous souhaitez obtenir l'espacement fourni par
constrained_layout
mais 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_layout
est désactivé pour les événements ZOOM
et 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_layout
fonctionnera 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.subplot
créera une nouvelle
GridSpec
instance 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')
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')
Text(0.5, 0.9895825, 'Mixed nrows, ncols')
De même,
subplot2grid
fonctionne 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')
Text(0.5, 0.9895825, 'subplot2grid')
Autres mises en garde #
constrained_layout
ne 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'
Figure
utilisationadd_artist()
. VoirConnectionPatch
pour 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 :
Il n'y avait pas assez de place pour les éléments que vous demandiez à dessiner.
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 GridSpec
classe. 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 left
et right
pour chaque colonne, et des variables bottom
et top
pour 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)
où bbox
est la boîte englobante serrée des axes, et pos
sa 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)
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)
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 :
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)
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 top
et
bottom
les 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 gridspec
fonctionnement 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)
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()
Durée totale d'exécution du script : (0 minutes 18,885 secondes)