Notiz
Klicken Sie hier , um den vollständigen Beispielcode herunterzuladen
Mehrere Achsen in einer Figur anordnen #
Oftmals werden mehr als eine Axt auf einer Figur gleichzeitig benötigt, normalerweise in einem regelmäßigen Raster organisiert. Matplotlib verfügt über eine Vielzahl von Tools für die Arbeit mit Rastern von Axes, die sich im Laufe der Geschichte der Bibliothek entwickelt haben. Hier werden wir die Tools besprechen, von denen wir glauben, dass Benutzer sie am häufigsten verwenden sollten, die Tools, die die Organisation von Axes untermauern, und einige der älteren Tools erwähnen.
Notiz
Matplotlib verwendet Axes , um auf den Zeichenbereich zu verweisen, der Daten, x- und y-Achse, Ticks, Beschriftungen, Titel usw. enthält. Siehe Teile einer Abbildung für weitere Details. Ein anderer häufig verwendeter Begriff ist "Subplot", der sich auf ein Axes bezieht, das sich in einem Raster mit anderen Axes-Objekten befindet.
Übersicht #
Erstellen Sie gitterförmige Kombinationen von Achsen #
subplots
Die primäre Funktion zum Erstellen von Figuren und einem Achsenraster. Es erstellt und platziert alle Achsen gleichzeitig auf der Figur und gibt ein Objektarray mit Griffen für die Achsen im Raster zurück. Siehe
Figure.subplots
.
oder
subplot_mosaic
Eine einfache Möglichkeit, Figuren und ein Achsenraster 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_mosaic
Komplexe und semantische Figurenkomposition .
Manchmal ist es natürlich, mehr als eine unterschiedliche Gruppe von Achsengittern zu haben, in diesem Fall hat Matplotlib das Konzept von SubFigure
:
SubFigure
Eine virtuelle Figur in einer Figur.
Zugrunde liegende Werkzeuge #
Dahinter stehen die Konzepte von a GridSpec
und a SubplotSpec
:
GridSpec
Gibt die Geometrie des Rasters an, in dem ein Nebenplot platziert wird. Die Anzahl der Zeilen und Spalten des Rasters muss eingestellt werden. Optional können die Teilplot-Layoutparameter (z. B. links, rechts usw.) angepasst werden.
SubplotSpec
Gibt den Ort der Nebenhandlung in der angegebenen
GridSpec
.
Einzelne Achsen gleichzeitig hinzufügen #
Die obigen Funktionen erstellen alle Achsen in einem einzigen Funktionsaufruf. Es ist auch möglich, Achsen einzeln hinzuzufügen, und so hat Matplotlib ursprünglich funktioniert. Dies ist im Allgemeinen weniger elegant und flexibel, aber manchmal nützlich für interaktives Arbeiten oder um eine Axt an einem benutzerdefinierten Ort zu platzieren:
add_axes
Fügt eine einzelne Achse an einer durch angegebenen Position in Bruchteilen der Breite oder Höhe der Figur hinzu.
[left, bottom, width, height]
subplot
oderFigure.add_subplot
Fügt einer Figur einen einzelnen Subplot hinzu, mit 1-basierter Indizierung (geerbt von Matlab). Spalten und Zeilen können überspannt werden, indem ein Bereich von Gitterzellen angegeben wird.
subplot2grid
Ähnlich wie
pyplot.subplot
, verwendet aber 0-basierte Indizierung und Zwei-D-Python-Slicing, um Zellen auszuwählen.
High-Level-Methoden zum Erstellen von Gittern #
Einfaches 2x2-Raster #
Wir können ein einfaches 2-mal-2-Achsraster erstellen, indem wir verwenden
subplots
. Es gibt eine Figure
Instanz und ein Array von Axes
Objekten zurück. Die Axes-Objekte können verwendet werden, um auf Methoden zuzugreifen, um Künstler auf den Axes zu platzieren; hier verwenden wir annotate
, aber andere Beispiele könnten plot
,
pcolormesh
, usw. sein.
import matplotlib.pyplot as plt
import numpy as np
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()')
Text(0.5, 0.9880942857142857, 'plt.subplots()')
Wir werden viele Achsen annotieren, also kapseln wir die Annotation, anstatt dieses große Stück Annotationscode jedes Mal zu haben, wenn wir es brauchen:
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 erreicht werden subplot_mosaic
, aber der Rückgabetyp ist ein Wörterbuch anstelle eines Arrays, in dem der Benutzer den Schlüsseln nützliche Bedeutungen geben kann. Hier stellen wir zwei Listen bereit, wobei jede Liste eine Zeile darstellt und jedes Element in der Liste einen Schlüssel, der die Spalte darstellt.
fig, axd = plt.subplot_mosaic([['upper left', 'upper right'],
['lower left', 'lower right']],
figsize=(5.5, 3.5), layout="constrained")
for k in axd:
annotate_axes(axd[k], f'axd["{k}"]', fontsize=14)
fig.suptitle('plt.subplot_mosaic()')
Text(0.5, 0.9880942857142857, 'plt.subplot_mosaic()')
Gitter mit festem Seitenverhältnis Achsen #
Achsen mit festem Seitenverhältnis sind für Bilder oder Karten üblich. Sie stellen jedoch eine Herausforderung für das Layout dar, da der Größe der Achsen zwei Arten von Beschränkungen auferlegt werden – dass sie in die Figur passen und dass sie ein festgelegtes Seitenverhältnis haben. Dies führt standardmäßig zu großen Lücken zwischen Achsen:
fig, axs = plt.subplots(2, 2, layout="constrained", figsize=(5.5, 3.5))
for ax in axs.flat:
ax.set_aspect(1)
fig.suptitle('Fixed aspect Axes')
Text(0.5, 0.9880942857142857, 'Fixed aspect Axes')
Eine Möglichkeit, dies zu beheben, besteht darin, das Seitenverhältnis der Figur so zu ändern, dass es dem Seitenverhältnis der Äxte nahekommt, dies erfordert jedoch Versuch und Irrtum. Matplotlib liefert auch layout="compressed"
, das mit einfachen Gittern arbeitet, um die Lücken zwischen den Achsen zu verringern. (Der mpl_toolkits
sieht auch vor ImageGrid
, einen ähnlichen Effekt zu erzielen, aber mit einer nicht standardmäßigen Axes-Klasse).
fig, axs = plt.subplots(2, 2, layout="compressed", figsize=(5.5, 3.5))
for ax in axs.flat:
ax.set_aspect(1)
fig.suptitle('Fixed aspect Axes: compressed')
Text(0.5, 0.9880942857142857, 'Fixed aspect Axes: compressed')
Achsen, die Zeilen oder Spalten in einem Raster überspannen #
Manchmal möchten wir, dass Achsen Zeilen oder Spalten des Rasters überspannen. Es gibt tatsächlich mehrere Möglichkeiten, dies zu erreichen, aber am bequemsten ist es wahrscheinlich, subplot_mosaic
eine der Tasten zu wiederholen:
fig, axd = plt.subplot_mosaic([['upper left', 'right'],
['lower left', 'right']],
figsize=(5.5, 3.5), layout="constrained")
for k in axd:
annotate_axes(axd[k], f'axd["{k}"]', fontsize=14)
fig.suptitle('plt.subplot_mosaic()')
Text(0.5, 0.9880942857142857, 'plt.subplot_mosaic()')
Unten finden Sie eine Beschreibung, wie Sie dasselbe mit
GridSpec
oder tun können subplot2grid
.
Variable Breiten oder Höhen in einem Raster #
Sowohl subplots
als subplot_mosaic
auch lassen zu, dass die Zeilen im Raster unterschiedliche Höhen und die Spalten unterschiedliche Breiten haben, indem das Schlüsselwortargument gridspec_kw verwendet wird . Von akzeptierte Abstandsparameter GridSpec
können an subplots
und
übergeben werden subplot_mosaic
:
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 in axd:
annotate_axes(axd[k], f'axd["{k}"]', fontsize=14)
fig.suptitle('plt.subplot_mosaic()')
Text(0.5, 0.9880942857142857, 'plt.subplot_mosaic()')
Layouts für verschachtelte Achsen #
Manchmal ist es hilfreich, zwei oder mehr Achsenraster zu haben, die möglicherweise nicht miteinander in Beziehung stehen müssen. Der einfachste Weg, dies zu erreichen, ist die Verwendung von Figure.subfigures
. Beachten Sie, dass die Unterfiguren-Layouts unabhängig sind, sodass die Axes-Stacheln in jeder Unterfigur nicht unbedingt ausgerichtet sind. Unten finden Sie eine ausführlichere Methode, um denselben Effekt mit zu erzielen GridSpecFromSubplotSpec
.
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('0.9')
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]')
Text(0.016867713730569944, 0.5, 'ylabel for subfigs[1]')
Es ist auch möglich, Achsen mithilfe subplot_mosaic
von verschachtelten Listen zu verschachteln. suptitle
Diese Methode verwendet keine Unterfiguren wie oben, daher fehlt die Möglichkeit, pro Unterfigur und supxlabel
usw. hinzuzufügen . Vielmehr ist es ein praktischer Wrapper um die subgridspec
unten beschriebene Methode.
Low-Level- und Advanced-Grid-Methoden #
Intern wird die Anordnung eines Axes-Rasters gesteuert, indem Instanzen von GridSpec
und erstellt werden SubplotSpec
. GridSpec definiert ein (möglicherweise uneinheitliches) Gitter aus Zellen. Die Indexierung in die GridSpec gibt eine SubplotSpec zurück, die eine oder mehrere Gitterzellen abdeckt und verwendet werden kann, um die Position einer Achse anzugeben.
Die folgenden Beispiele zeigen, wie Low-Level-Methoden verwendet werden, um Axes mithilfe von GridSpec - Objekten anzuordnen.
Einfaches 2x2-Raster #
Wir können ein 2x2-Raster auf die gleiche Weise erstellen wie
: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')
Text(0.5, 0.9880942857142857, 'Manually added subplots using add_gridspec')
Achsen, die Zeilen oder Gitter in einem Gitter überspannen #
Wir können das Spezifikations -Array mit der NumPy-Slice-Syntax indizieren,
und die neuen Axes überspannen das Slice. 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')
Text(0.5, 0.9880942857142857, 'Manually added subplots, spanning a column')
Manuelle Anpassungen an ein GridSpec- Layout #
Wenn explizit eine GridSpec verwendet wird, können Sie die Layoutparameter von Subplots anpassen, die aus der GridSpec erstellt werden . Beachten Sie, dass diese Option nicht mit constrained_layout
oder
kompatibel ist, die sowohl links als auch rechtsFigure.tight_layout
ignorieren und die Größe der Teilplots anpassen, um die Figur auszufüllen. Normalerweise erfordert eine solche manuelle Platzierung Iterationen, damit die Tick-Beschriftungen der Achsen die Achsen nicht überlappen.
Diese Abstandsparameter können auch an subplots
und
subplot_mosaic
als Argument gridspec_kw übergeben werden .
fig = plt.figure(layout=None, facecolor='0.9')
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')
Text(0.5, 0.98, 'Manual gridspec with right=0.75')
Verschachtelte Layouts mit SubplotSpec #
Sie können ein verschachteltes Layout ähnlich wie subfigures
mit
erstellen subgridspec
. Hier sind die Stacheln der Achsen
ausgerichtet.
Beachten Sie, dass dies auch über die ausführlichere verfügbar ist
gridspec.GridSpecFromSubplotSpec
.
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')
Text(0.5, 0.99131875, 'nested gridspecs')
Hier ist ein anspruchsvolleres Beispiel für verschachtelte GridSpec : Wir erstellen ein äußeres 4x4-Raster, wobei jede Zelle ein inneres 3x3-Raster aus Achsen enthält. Wir skizzieren das äußere 4x4-Gitter, indem wir die entsprechenden Stacheln in jedem der inneren 3x3-Gitter verstecken.
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), constrained_layout=False)
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()
Mehr lesen #
Weitere Details zu Subplot-Mosaik .
Weitere Details zum eingeschränkten Layout , das in den meisten dieser Beispiele zum Ausrichten der Abstände verwendet wird.
Verweise
In diesem Beispiel wird die Verwendung der folgenden Funktionen, Methoden, Klassen und Module gezeigt:
Gesamtlaufzeit des Skripts: ( 0 Minuten 13.006 Sekunden)