Hinweis
Zum Ende springen, um den vollständigen Beispielcode herunterzuladen.
Anordnung mehrerer Achsen in einer Figur#
Oftmals möchte man mehrere Achsen gleichzeitig auf einer Figur haben, üblicherweise in einem regelmäßigen Gitter angeordnet. Matplotlib bietet eine Vielzahl von Werkzeugen für die Arbeit mit Achsen-Gittern, die sich im Laufe der Entwicklung der Bibliothek entwickelt haben. Hier werden wir die Werkzeuge diskutieren, die wir für die häufigste Verwendung durch Benutzer halten, die Werkzeuge, die die Grundlage für die Organisation von Achsen bilden, und einige der älteren Werkzeuge erwähnen.
Hinweis
Matplotlib verwendet Achsen (Axes), um den Zeichenbereich zu bezeichnen, der Daten, x- und y-Achsen, Ticks, Beschriftungen, Titel usw. enthält. Weitere Details finden Sie unter Teile einer Figur. Ein weiterer Begriff, der häufig verwendet wird, ist "Subplot", der sich auf eine Achse in einem Gitter mit anderen Achsen-Objekten bezieht.
Übersicht#
Erstellung von gitterförmigen Kombinationen von Achsen#
subplotsDie primäre Funktion zur Erstellung von Figuren und einem Gitter von Achsen. Sie erstellt und platziert alle Achsen auf der Figur gleichzeitig und gibt ein Objekt-Array mit Handles für die Achsen im Gitter zurück. Siehe
Figure.subplots.
oder
subplot_mosaicEine einfache Möglichkeit, Figuren und ein Gitter von Achsen zu erstellen, mit der zusätzlichen Flexibilität, dass Achsen auch Zeilen oder Spalten überspannen können. Die Achsen werden in einem beschrifteten Wörterbuch anstelle eines Arrays zurückgegeben. Siehe auch
Figure.subplot_mosaicund Komplexe und semantische Figurenzusammensetzung (subplot_mosaic).
Manchmal ist es natürlich, mehr als eine einzelne Gruppe von Achsen-Gittern zu haben. In diesem Fall hat Matplotlib das Konzept von SubFigure
SubFigureEine virtuelle Figur innerhalb einer Figur.
Zugrundeliegende Werkzeuge#
Zugrundeliegend sind die Konzepte eines GridSpec und eines SubplotSpec
GridSpecDefiniert die Geometrie des Gitters, in dem ein Subplot platziert wird. Die Anzahl der Zeilen und Spalten des Gitters muss festgelegt werden. Optional können die Layout-Parameter des Subplots (z. B. links, rechts usw.) angepasst werden.
SubplotSpecDefiniert die Position des Subplots im gegebenen
GridSpec.
Hinzufügen einzelner Achsen zu einer Zeit#
Die oben genannten Funktionen erstellen alle Achsen in einem einzigen Funktionsaufruf. Es ist auch möglich, Achsen einzeln hinzuzufügen, und so hat es ursprünglich funktioniert. Dies ist im Allgemeinen weniger elegant und flexibel, obwohl es manchmal für interaktive Arbeiten oder zur Platzierung einer Achse an einer benutzerdefinierten Position nützlich ist.
add_axesFügt eine einzelne Achse an einer Position hinzu, die durch
[links, unten, breite, höhe]in Bruchteilen der Figurenhöhe oder -breite angegeben ist.subplotoderFigure.add_subplotFügt einen einzelnen Subplot zu einer Figur hinzu, mit 1-basierter Indizierung (von Matlab geerbt). Spalten und Zeilen können durch Angabe eines Bereichs von Gitterzellen überspannt werden.
subplot2gridÄhnlich wie
pyplot.subplot, verwendet jedoch 0-basierte Indizierung und zweidimensionale Python-Slicing zur Auswahl von Zellen.
Als einfaches Beispiel für das manuelle Hinzufügen einer Achse ax fügen wir eine 3 Zoll x 2 Zoll große Achse zu einer 4 Zoll x 3 Zoll großen Figur hinzu. Beachten Sie, dass die Position des Subplots als [links, unten, breite, höhe] in Einheiten angegeben wird, die auf die Figurengröße normalisiert sind.

Hochrangige Methoden zur Erstellung von Gittern#
Grundlegendes 2x2-Gitter#
Wir können ein grundlegendes 2x2-Gitter von Achsen mit subplots erstellen. Es gibt eine Figure-Instanz und ein Array von Axes-Objekten zurück. Die Achsen-Objekte können verwendet werden, um auf Methoden zum Platzieren von Künstlern auf der Achse zuzugreifen. Hier verwenden wir annotate, aber andere Beispiele könnten plot, pcolormesh usw. sein.
fig, axs = plt.subplots(ncols=2, nrows=2, figsize=(5.5, 3.5),
layout="constrained")
# add an artist, in this case a nice label in the middle...
for row in range(2):
for col in range(2):
axs[row, col].annotate(f'axs[{row}, {col}]', (0.5, 0.5),
transform=axs[row, col].transAxes,
ha='center', va='center', fontsize=18,
color='darkgrey')
fig.suptitle('plt.subplots()')

Wir werden viele Achsen annotieren, also kapseln wir die Annotation, anstatt diesen großen Block an Annotationscode jedes Mal zu wiederholen, wenn wir ihn benötigen.
def annotate_axes(ax, text, fontsize=18):
ax.text(0.5, 0.5, text, transform=ax.transAxes,
ha="center", va="center", fontsize=fontsize, color="darkgrey")
Der gleiche Effekt kann mit subplot_mosaic erzielt werden, aber der Rückgabetyp ist ein Wörterbuch anstelle eines Arrays, wobei der Benutzer den Schlüsseln aussagekräftige Bedeutungen geben kann. Hier stellen wir zwei Listen bereit, wobei jede Liste eine Zeile und jedes Element in der Liste einen Schlüssel darstellt, der die Spalte repräsentiert.
fig, axd = plt.subplot_mosaic([['upper left', 'upper right'],
['lower left', 'lower right']],
figsize=(5.5, 3.5), layout="constrained")
for k, ax in axd.items():
annotate_axes(ax, f'axd[{k!r}]', fontsize=14)
fig.suptitle('plt.subplot_mosaic()')

Gitter mit Achsen festen Seitenverhältnisses#
Achsen mit festem Seitenverhältnis sind üblich für Bilder oder Karten. Sie stellen jedoch eine Herausforderung für das Layout dar, da zwei Sätze von Beschränkungen für die Größe der Achsen auferlegt werden: Sie müssen in die Figur passen und sie haben ein festgelegtes Seitenverhältnis. Dies führt standardmäßig zu großen Lücken zwischen den Achsen.
fig, axs = plt.subplots(2, 2, layout="constrained",
figsize=(5.5, 3.5), facecolor='lightblue')
for ax in axs.flat:
ax.set_aspect(1)
fig.suptitle('Fixed aspect Axes')

Ein Weg, dies zu beheben, ist die Änderung des Seitenverhältnisses der Figur, um nahe am Seitenverhältnis der Achsen zu liegen, dies erfordert jedoch Versuch und Irrtum. Matplotlib bietet auch layout="compressed", was bei einfachen Gittern funktioniert, um die Lücken zwischen den Achsen zu reduzieren. (Die mpl_toolkits bieten auch ImageGrid, um einen ähnlichen Effekt zu erzielen, jedoch mit einer nicht standardmäßigen Achsenklasse).
fig, axs = plt.subplots(2, 2, layout="compressed", figsize=(5.5, 3.5),
facecolor='lightblue')
for ax in axs.flat:
ax.set_aspect(1)
fig.suptitle('Fixed aspect Axes: compressed')

Achsen, die Zeilen oder Spalten in einem Gitter überspannen#
Manchmal möchten wir, dass Achsen Zeilen oder Spalten des Gitters überspannen. Es gibt tatsächlich mehrere Möglichkeiten, dies zu erreichen, aber die bequemste ist wahrscheinlich die Verwendung von subplot_mosaic, indem einer der Schlüssel wiederholt wird.
fig, axd = plt.subplot_mosaic([['upper left', 'right'],
['lower left', 'right']],
figsize=(5.5, 3.5), layout="constrained")
for k, ax in axd.items():
annotate_axes(ax, f'axd[{k!r}]', fontsize=14)
fig.suptitle('plt.subplot_mosaic()')

Siehe unten für die Beschreibung, wie dasselbe mit GridSpec oder subplot2grid erreicht wird.
Variable Breiten oder Höhen in einem Gitter#
Sowohl subplots als auch subplot_mosaic erlauben es, dass die Zeilen im Gitter unterschiedliche Höhen und die Spalten unterschiedliche Breiten haben, indem das Schlüsselwortargument gridspec_kw verwendet wird. Abstands-Parameter, die von GridSpec akzeptiert werden, können an subplots und subplot_mosaic übergeben werden.
gs_kw = dict(width_ratios=[1.4, 1], height_ratios=[1, 2])
fig, axd = plt.subplot_mosaic([['upper left', 'right'],
['lower left', 'right']],
gridspec_kw=gs_kw, figsize=(5.5, 3.5),
layout="constrained")
for k, ax in axd.items():
annotate_axes(ax, f'axd[{k!r}]', fontsize=14)
fig.suptitle('plt.subplot_mosaic()')

Verschachtelte Achsen-Layouts#
Manchmal ist es hilfreich, zwei oder mehr Gitter von Achsen zu haben, die nicht unbedingt miteinander in Beziehung stehen müssen. Der einfachste Weg, dies zu erreichen, ist die Verwendung von Figure.subfigures. Beachten Sie, dass die Subfiguren-Layouts unabhängig sind, sodass die Achsen-Spine in jeder Subfigure nicht notwendigerweise ausgerichtet ist. Siehe unten für einen ausführlicheren Weg, um denselben Effekt mit GridSpecFromSubplotSpec zu erzielen.
fig = plt.figure(layout="constrained")
subfigs = fig.subfigures(1, 2, wspace=0.07, width_ratios=[1.5, 1.])
axs0 = subfigs[0].subplots(2, 2)
subfigs[0].set_facecolor('lightblue')
subfigs[0].suptitle('subfigs[0]\nLeft side')
subfigs[0].supxlabel('xlabel for subfigs[0]')
axs1 = subfigs[1].subplots(3, 1)
subfigs[1].suptitle('subfigs[1]')
subfigs[1].supylabel('ylabel for subfigs[1]')

Es ist auch möglich, Achsen mit subplot_mosaic unter Verwendung verschachtelter Listen zu verschachteln. Diese Methode verwendet keine Subfiguren wie oben, daher fehlt ihr die Möglichkeit, pro Subfigure suptitle und supxlabel usw. hinzuzufügen. Vielmehr ist sie eine praktische Wrapper-Funktion um die unten beschriebene subgridspec-Methode.

Niedrigrangige und fortgeschrittene Gittermethoden#
Intern wird die Anordnung eines Achsen-Gitters durch die Erstellung von Instanzen von GridSpec und SubplotSpec gesteuert. GridSpec definiert ein (möglicherweise nicht gleichmäßiges) Gitter von Zellen. Das Indizieren in GridSpec gibt ein SubplotSpec zurück, das eine oder mehrere Gitterzellen abdeckt und zur Angabe der Position einer Achse verwendet werden kann.
Die folgenden Beispiele zeigen, wie Niedrigrangige Methoden zur Anordnung von Achsen mit GridSpec-Objekten verwendet werden.
Grundlegendes 2x2-Gitter#
Wir können ein 2x2-Gitter auf die gleiche Weise erreichen wie mit plt.subplots(2, 2)
fig = plt.figure(figsize=(5.5, 3.5), layout="constrained")
spec = fig.add_gridspec(ncols=2, nrows=2)
ax0 = fig.add_subplot(spec[0, 0])
annotate_axes(ax0, 'ax0')
ax1 = fig.add_subplot(spec[0, 1])
annotate_axes(ax1, 'ax1')
ax2 = fig.add_subplot(spec[1, 0])
annotate_axes(ax2, 'ax2')
ax3 = fig.add_subplot(spec[1, 1])
annotate_axes(ax3, 'ax3')
fig.suptitle('Manually added subplots using add_gridspec')

Achsen, die Zeilen oder Gitter in einem Gitter überspannen#
Wir können das spec-Array mit der NumPy Slice-Syntax indizieren und die neue Achse wird den Slice überspannen. Dies wäre dasselbe wie fig, axd = plt.subplot_mosaic([['ax0', 'ax0'], ['ax1', 'ax2']], ...)
fig = plt.figure(figsize=(5.5, 3.5), layout="constrained")
spec = fig.add_gridspec(2, 2)
ax0 = fig.add_subplot(spec[0, :])
annotate_axes(ax0, 'ax0')
ax10 = fig.add_subplot(spec[1, 0])
annotate_axes(ax10, 'ax10')
ax11 = fig.add_subplot(spec[1, 1])
annotate_axes(ax11, 'ax11')
fig.suptitle('Manually added subplots, spanning a column')

Manuelle Anpassungen eines GridSpec-Layouts#
Wenn ein GridSpec explizit verwendet wird, können Sie die Layout-Parameter von Subplots anpassen, die aus dem GridSpec erstellt werden. Beachten Sie, dass diese Option nicht mit constrained layout oder Figure.tight_layout kompatibel ist, die beide links und rechts ignorieren und die Subplotgrößen anpassen, um die Figur auszufüllen. Normalerweise erfordert eine solche manuelle Platzierung Iterationen, um zu vermeiden, dass die Achsen-Tick-Beschriftungen mit den Achsen überlappen.
Diese Abstandsparameter können auch als gridspec_kw-Argument an subplots und subplot_mosaic übergeben werden.
fig = plt.figure(layout=None, facecolor='lightblue')
gs = fig.add_gridspec(nrows=3, ncols=3, left=0.05, right=0.75,
hspace=0.1, wspace=0.05)
ax0 = fig.add_subplot(gs[:-1, :])
annotate_axes(ax0, 'ax0')
ax1 = fig.add_subplot(gs[-1, :-1])
annotate_axes(ax1, 'ax1')
ax2 = fig.add_subplot(gs[-1, -1])
annotate_axes(ax2, 'ax2')
fig.suptitle('Manual gridspec with right=0.75')

Verschachtelte Layouts mit SubplotSpec#
Sie können verschachtelte Layouts ähnlich wie mit subfigures mit subgridspec erstellen. Hier sind die Achsen-Spines ausgerichtet.
Beachten Sie, dass dies auch über das ausführlichere gridspec.GridSpecFromSubplotSpec verfügbar ist.
fig = plt.figure(layout="constrained")
gs0 = fig.add_gridspec(1, 2)
gs00 = gs0[0].subgridspec(2, 2)
gs01 = gs0[1].subgridspec(3, 1)
for a in range(2):
for b in range(2):
ax = fig.add_subplot(gs00[a, b])
annotate_axes(ax, f'axLeft[{a}, {b}]', fontsize=10)
if a == 1 and b == 1:
ax.set_xlabel('xlabel')
for a in range(3):
ax = fig.add_subplot(gs01[a])
annotate_axes(ax, f'axRight[{a}, {b}]')
if a == 2:
ax.set_ylabel('ylabel')
fig.suptitle('nested gridspecs')

Hier ist ein anspruchsvolleres Beispiel für verschachtelte GridSpec: Wir erstellen ein äußeres 4x4-Gitter, wobei jede Zelle ein inneres 3x3-Gitter von Achsen enthält. Wir umreißen das äußere 4x4-Gitter, indem wir die entsprechenden Spines in jedem der inneren 3x3-Gitter ausblenden.
def squiggle_xy(a, b, c, d, i=np.arange(0.0, 2*np.pi, 0.05)):
return np.sin(i*a)*np.cos(i*b), np.sin(i*c)*np.cos(i*d)
fig = plt.figure(figsize=(8, 8), layout='constrained')
outer_grid = fig.add_gridspec(4, 4, wspace=0, hspace=0)
for a in range(4):
for b in range(4):
# gridspec inside gridspec
inner_grid = outer_grid[a, b].subgridspec(3, 3, wspace=0, hspace=0)
axs = inner_grid.subplots() # Create all subplots for the inner grid.
for (c, d), ax in np.ndenumerate(axs):
ax.plot(*squiggle_xy(a + 1, b + 1, c + 1, d + 1))
ax.set(xticks=[], yticks=[])
# show only the outside spines
for ax in fig.get_axes():
ss = ax.get_subplotspec()
ax.spines.top.set_visible(ss.is_first_row())
ax.spines.bottom.set_visible(ss.is_last_row())
ax.spines.left.set_visible(ss.is_first_col())
ax.spines.right.set_visible(ss.is_last_col())
plt.show()

Weitere Lektüre#
Mehr Details zu subplot mosaic.
Mehr Details zu constrained layout, das zur Ausrichtung von Abständen in den meisten dieser Beispiele verwendet wird.
Referenzen
Die Verwendung der folgenden Funktionen, Methoden, Klassen und Module wird in diesem Beispiel gezeigt
Gesamtlaufzeit des Skripts: (0 Minuten 14,470 Sekunden)