Notiz
Klicken Sie hier , um den vollständigen Beispielcode herunterzuladen
Leitfaden für eingeschränktes Layout #
So verwenden Sie eingeschränktes Layout, um Diagramme sauber in Ihre Figur einzupassen.
constrained_layout passt Subplots und Dekorationen wie Legenden und Farbbalken automatisch so an, dass sie in das Figurenfenster passen, während das vom Benutzer gewünschte logische Layout so gut wie möglich erhalten bleibt.
constrained_layout ähnelt tight_layout , verwendet jedoch einen Constraint-Solver, um die Größe der Achsen zu bestimmen, die es ihnen ermöglicht, zu passen.
constrained_layout muss normalerweise aktiviert werden, bevor einer Figur Achsen hinzugefügt werden. Dazu gibt es zwei Möglichkeiten
Verwenden Sie das entsprechende Argument für
subplots()
oderfigure()
, z. B.:plt.subplots(layout="constrained")
aktivieren Sie es über rcParams , wie:
plt.rcParams['figure.constrained_layout.use'] = True
Diese werden in den folgenden Abschnitten ausführlich beschrieben.
Einfaches Beispiel #
In Matplotlib wird die Position von Achsen (einschließlich Subplots) in normalisierten Figurenkoordinaten angegeben. Es kann vorkommen, dass Ihre Achsenbeschriftungen oder -titel (oder manchmal sogar Teilstrichbeschriftungen) außerhalb des Abbildungsbereichs liegen und daher abgeschnitten werden.
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)
Um dies zu verhindern, muss die Position der Achsen angepasst werden. Bei Nebenhandlungen kann dies manuell erfolgen, indem Sie die Nebenhandlungsparameter mit anpassen Figure.subplots_adjust
. Wenn Sie Ihre Zahl jedoch mit dem layout="constrained"
Schlüsselwortargument # angeben, wird die Anpassung # automatisch durchgeführt.
fig, ax = plt.subplots(layout="constrained")
example_plot(ax, fontsize=24)
Wenn Sie mehrere Subplots haben, sehen Sie oft Beschriftungen verschiedener Achsen, die sich überlappen.
fig, axs = plt.subplots(2, 2, layout=None)
for ax in axs.flat:
example_plot(ax)
Die Angabe layout="constrained"
im Aufruf von plt.subplots
bewirkt, dass das Layout ordnungsgemäß eingeschränkt wird.
fig, axs = plt.subplots(2, 2, layout="constrained")
for ax in axs.flat:
example_plot(ax)
Farbbalken #
Wenn Sie einen Farbbalken mit erstellen Figure.colorbar
, müssen Sie Platz dafür schaffen. constrained_layout
macht das automatisch. Beachten Sie, dass die Angabe use_gridspec=True
ignoriert wird, da diese Option zur Verbesserung des Layouts über verwendet wird
tight_layout
.
Notiz
Für die pcolormesh
Schlüsselwortargumente ( pc_kwargs
) verwenden wir ein Wörterbuch. Im Folgenden weisen wir einer Reihe von Achsen einen Farbbalken zu, die jeweils ein ScalarMappable
; Durch die Angabe der Norm und der Farbtabelle wird sichergestellt, dass der Farbbalken für alle Achsen genau ist.
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>
Wenn Sie eine Liste von Achsen (oder einen anderen iterierbaren Container) für das
ax
Argument von colorbar
angeben, nimmt constrained_layout Platz von den angegebenen Achsen ein.
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>
Wenn Sie eine Liste von Achsen innerhalb eines Achsenrasters angeben, nimmt der Farbbalken angemessen Platz ein und hinterlässt eine Lücke, aber alle Unterdiagramme haben immer noch dieselbe Größe.
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>
Untertitel #
constrained_layout
kann auch Platz schaffen 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')
Legenden #
Legenden können außerhalb ihrer übergeordneten Achse platziert werden. Das eingeschränkte Layout wurde entwickelt, um dies für Axes.legend()
. Das eingeschränkte Layout verarbeitet jedoch (noch) keine Legenden, die über erstellt wurden
.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>
Dies wird jedoch Platz von einem Nebenplot-Layout stehlen:
<matplotlib.legend.Legend object at 0x7f2cf99852a0>
Damit eine Legende oder ein anderer Künstler keinen Platz aus dem Layout der Nebenhandlung stiehlt, können wir leg.set_in_layout(False)
. Das kann natürlich dazu führen, dass die Legende abgeschnitten wird, kann aber nützlich sein, wenn die Handlung nachträglich mit aufgerufen wird . Beachten Sie jedoch, dass der Status der Legende erneut umgeschaltet werden muss, damit die gespeicherte Datei funktioniert, und wir müssen manuell ein Zeichnen auslösen, wenn wir möchten, dass constrained_layout die Größe der Achsen vor dem Drucken anpasst.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
Die gespeicherte Datei sieht so aus:
Eine bessere Möglichkeit, diese Unbeholfenheit zu umgehen, besteht darin, einfach die Legendenmethode zu verwenden, die von bereitgestellt wird 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
Die gespeicherte Datei sieht so aus:
Polsterung und Abstand #
Das Auffüllen zwischen den Achsen wird horizontal durch w_pad und
wspace und vertikal durch h_pad und hspace gesteuert . Diese können über bearbeitet werden set
. w/h_pad sind der Mindestabstand um die Achsen in Zolleinheiten:
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)
Der Abstand zwischen Subplots wird weiter durch wspace und hspace festgelegt . Diese werden als Bruchteil der Größe der Unterparzellengruppe insgesamt angegeben. Wenn diese Werte kleiner als w_pad oder h_pad sind, werden stattdessen die festen Pads verwendet. Beachten Sie im Folgenden, dass sich der Abstand an den Rändern nicht von oben ändert, der Abstand zwischen den Unterplots jedoch.
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)
Wenn es mehr als zwei Spalten gibt, wird der wspace zwischen ihnen geteilt, also wird der wspace hier in 2 geteilt, mit einem wspace von 0,1 zwischen jeder Spalte:
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 haben auch optionale hspace- und wspace- Schlüsselwortargumente, die anstelle der von gesetzten Pads verwendet werden 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)
Abstand mit Farbbalken #
Farbbalken werden in einem Abstand Pad von ihrem übergeordneten Element platziert, wobei das Pad einen Bruchteil der Breite des übergeordneten Elements ausmacht. Der Abstand zum nächsten Subplot ist dann durch w/hspace gegeben .
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 #
Es gibt fünf rcParams
, die gesetzt werden können, entweder in einem Skript oder in der matplotlibrc
Datei. Sie haben alle das Präfix figure.constrained_layout
:
use : Ob constrained_layout verwendet werden soll. Der Standardwert ist False
w_pad , h_pad : Padding um Achsenobjekte herum. Float, der Zoll darstellt. Standard ist 3./72. Zoll (3 Punkte)
wspace , hspace : Abstand zwischen Subplot-Gruppen. Gleitkommazahl, die einen Bruchteil der zu trennenden Teilflächenbreiten darstellt. Der Standardwert ist 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)
Mit GridSpec # verwenden
constrained_layout soll mit subplots()
,
subplot_mosaic()
oder
GridSpec()
mit
verwendet werden add_subplot()
.
Beachten Sie das im Folgendenlayout="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)
Kompliziertere Gridspec-Layouts sind möglich. Beachten Sie, dass wir hier die Komfortfunktionen add_gridspec
und
verwenden 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')
Beachten Sie, dass die linke und die rechte Spalte oben nicht die gleiche vertikale Ausdehnung haben. Wenn wir möchten, dass die Ober- und Unterseite der beiden Gitter aneinander ausgerichtet sind, müssen sie sich in derselben Gitterspezifikation befinden. Wir müssen diese Figur ebenfalls vergrößern, damit die Achsen nicht auf die Höhe Null zusammenbrechen:
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')
In diesem Beispiel werden zwei Gridspecs verwendet, damit sich der Farbbalken nur auf einen Satz von pcolors bezieht. Beachten Sie, dass die linke Spalte aus diesem Grund breiter ist als die beiden rechten Spalten. Wenn Sie wollten, dass die Subplots die gleiche Größe haben, brauchten Sie natürlich nur eine Gridspec. Beachten Sie, dass der gleiche Effekt mit erreicht werden kann 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>
Anstatt Subgridspecs zu verwenden, stellt Matplotlib jetzt bereit subfigures
, die auch mit funktionieren 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')
Achsenpositionen manuell einstellen #
Es kann gute Gründe geben, eine Achsenposition manuell festzulegen. Ein manueller Aufruf von set_position
setzt die Achsen so, dass constrained_layout keine Auswirkung mehr darauf hat. (Beachten Sie, dass constrained_layout
immer noch Platz für die bewegten Achsen bleibt).
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])
Raster von Achsen mit festem Seitenverhältnis: "komprimiertes" Layout #
constrained_layout
arbeitet auf dem Raster der "ursprünglichen" Positionen für Achsen. Wenn Achsen jedoch feste Seitenverhältnisse haben, wird eine Seite normalerweise kürzer gemacht und hinterlässt große Lücken in der verkürzten Richtung. Im Folgenden sind die Achsen quadratisch, aber die Figur ziemlich breit, sodass es eine horizontale Lücke gibt:
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'")
Eine offensichtliche Möglichkeit, dies zu beheben, besteht darin, die Figurengröße quadratischer zu machen, aber das genaue Schließen der Lücken erfordert Versuch und Irrtum. Für einfache Raster von Achsen können wir layout="compressed"
die Arbeit für uns erledigen:
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'")
Manuelles Ausschalten constrained_layout
#
constrained_layout
passt normalerweise die Achsenpositionen bei jedem Zeichnen der Figur an. Wenn Sie den von bereitgestellten Abstand erhalten möchten, ihn
constrained_layout
aber nicht aktualisieren lassen möchten, führen Sie die erste Zeichnung durch und rufen Sie dann auf fig.set_layout_engine(None)
. Dies ist möglicherweise nützlich für Animationen, bei denen die Tick-Labels die Länge ändern können.
Beachten Sie, dass constrained_layout
für ZOOM
und PAN
GUI-Ereignisse für die Backends, die die Symbolleiste verwenden, deaktiviert sind. Dadurch wird verhindert, dass sich die Achsen während des Zoomens und Schwenkens ändern.
Einschränkungen #
Inkompatible Funktionen #
constrained_layout
funktioniert mit pyplot.subplot
, aber nur, wenn die Anzahl der Zeilen und Spalten für jeden Aufruf gleich ist. Der Grund dafür ist, dass jeder Aufruf von pyplot.subplot
eine neue
GridSpec
Instanz erstellt, wenn die Geometrie nicht dieselbe ist, und
constrained_layout
. Also folgendes funktioniert gut:
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')
aber das Folgende führt zu einem schlechten Layout:
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')
Ähnlich
subplot2grid
funktioniert es mit der gleichen Einschränkung, die nrows und ncols nicht ändern können, damit das Layout gut aussieht.
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')
Andere Vorbehalte #
constrained_layout
berücksichtigt nur Ticklabels, Achsenbeschriftungen, Titel und Legenden. Somit können andere Künstler abgeschnitten werden und sich auch überlappen.Es wird davon ausgegangen, dass der zusätzliche Platz, der für Teilstrichbeschriftungen, Achsenbeschriftungen und Titel benötigt wird, unabhängig von der ursprünglichen Position der Achsen ist. Dies ist oft der Fall, aber es gibt seltene Fälle, in denen dies nicht der Fall ist.
Es gibt kleine Unterschiede in der Art und Weise, wie die Backends mit der Wiedergabe von Schriftarten umgehen, sodass die Ergebnisse nicht pixelidentisch sind.
Ein Künstler, der Achsenkoordinaten verwendet, die über die Achsenbegrenzung hinausgehen, führt zu ungewöhnlichen Layouts, wenn er einer Achse hinzugefügt wird. Dies kann vermieden werden, indem der Künstler direkt zur
Figure
Verwendung hinzugefügt wirdadd_artist()
. SieheConnectionPatch
für ein Beispiel.
Fehlersuche #
Ein eingeschränktes Layout kann auf etwas unerwartete Weise fehlschlagen. Da ein Constraint-Solver verwendet wird, kann der Solver Lösungen finden, die mathematisch korrekt sind, aber überhaupt nicht das sind, was der Benutzer will. Der übliche Versagensmodus besteht darin, dass alle Größen auf ihren kleinsten zulässigen Wert zusammenbrechen. Wenn dies passiert, hat dies einen von zwei Gründen:
Es war nicht genug Platz für die Elemente, die Sie zeichnen wollten.
Es gibt einen Fehler - öffnen Sie in diesem Fall ein Problem unter https://github.com/matplotlib/matplotlib/issues .
Wenn es einen Fehler gibt, melden Sie ihn bitte mit einem eigenständigen Beispiel, das keine externen Daten oder Abhängigkeiten (außer numpy) erfordert.
Hinweise zum Algorithmus #
Der Algorithmus für die Einschränkung ist relativ einfach, aber aufgrund der komplexen Art und Weise, wie wir eine Figur gestalten können, etwas komplex.
Das Layout in Matplotlib erfolgt mit Gridspecs über die GridSpec
Klasse. Eine Gitterspezifikation ist eine logische Unterteilung der Figur in Zeilen und Spalten, wobei die relative Breite der Achsen in diesen Zeilen und Spalten durch width_ratios und height_ratios festgelegt wird .
In constrained_layout bekommt jede Gridspec ein damit verbundenes Layoutgrid. Das Layoutgrid hat eine Reihe von left
und - right
Variablen für jede Spalte und bottom
und - top
Variablen für jede Zeile, und außerdem hat es einen Rand für links, rechts, unten und oben. In jeder Reihe werden die unteren/oberen Ränder verbreitert, bis alle Dekorateure in dieser Reihe untergebracht sind. Ähnlich für Spalten und die linken/rechten Ränder.
Einfacher Fall: eine Achse #
Für eine einzelne Achse ist das Layout einfach. Es gibt ein Eltern-Layoutgrid für die Figur, das aus einer Spalte und einer Reihe besteht, und ein Kind-Layoutgrid für die Gridspec, die die Achsen enthält, wiederum bestehend aus einer Reihe und einer Spalte. Auf jeder Seite der Achsen wird Platz für die "Dekorationen" geschaffen. Im Code wird dies durch die Einträge in
do_constrained_layout()
like erreicht:
gridspec._layoutgrid[0, 0].edit_margin_min('left',
-bbox.x0 + pos.x0 + w_pad)
wo bbox
ist der enge Begrenzungsrahmen der Achsen und pos
seine Position. Beachten Sie, wie die vier Ränder die Achsendekorationen umfassen.
from matplotlib._layoutgrid import plot_children
fig, ax = plt.subplots(layout="constrained")
example_plot(ax, fontsize=24)
plot_children(fig)
Einfacher Fall: zwei Achsen #
Wenn mehrere Achsen vorhanden sind, werden ihre Layouts auf einfache Weise gebunden. In diesem Beispiel hat die linke Achse viel größere Dekorationen als die rechte, aber sie teilen sich einen unteren Rand, der groß genug gemacht wird, um das größere xlabel aufzunehmen. Gleiches gilt für den gemeinsamen oberen Rand. Der linke und der rechte Rand werden nicht geteilt und dürfen daher unterschiedlich sein.
fig, ax = plt.subplots(1, 2, layout="constrained")
example_plot(ax[0], fontsize=32)
example_plot(ax[1], fontsize=8)
plot_children(fig)
Zwei Achsen und Farbbalken #
Ein Farbbalken ist einfach ein weiteres Element, das den Rand der übergeordneten Zelle des Layoutrasters erweitert:
Mit einer Rasterspezifikation verknüpfter Farbbalken #
Wenn ein Farbbalken zu mehr als einer Zelle des Rasters gehört, dann macht er für jede einen größeren Rand:
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)
Ungleich große Äxte #
Es gibt zwei Möglichkeiten, Achsen in einem Gridspec-Layout eine ungleichmäßige Größe zu geben, entweder indem Sie sie so angeben, dass sie Gridspecs-Zeilen oder -Spalten kreuzen, oder indem Sie Breiten- und Höhenverhältnisse angeben.
Hier wird die erste Methode verwendet. Beachten Sie, dass die Mitte top
und
die bottom
Ränder nicht von der linken Spalte beeinflusst werden. Dies ist eine bewusste Entscheidung des Algorithmus und führt dazu, dass die beiden rechten Achsen die gleiche Höhe haben, aber nicht 1/2 der Höhe der linken Achsen. Dies steht im Einklang mit der Funktionsweise gridspec
ohne eingeschränktes Layout.
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)
Ein Fall, der eine Verfeinerung erfordert, ist, wenn Ränder keine Künstler haben, die ihre Breite einschränken. Im folgenden Fall haben der rechte Rand für Spalte 0 und der linke Rand für Spalte 3 keine Randkünstler, um ihre Breite festzulegen, also nehmen wir die maximale Breite der Randbreiten, die Künstler haben. Dadurch haben alle Achsen die gleiche Größe:
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()
Gesamtlaufzeit des Skripts: ( 0 Minuten 18.885 Sekunden)