Hinweis
Zum Ende gehen, um den gesamten Beispielcode herunterzuladen.
Tight-Layout-Leitfaden#
So verwenden Sie tight-layout, um Plots sauber in Ihre Abbildung einzupassen.
Tipp
tight_layout war die erste Layout-Engine in Matplotlib. Das modernere und leistungsfähigere Constrained Layout sollte normalerweise stattdessen verwendet werden.
tight_layout passt die Subplot-Parameter automatisch an, sodass die Subplot(s) in den Abbildungsbereich passen. Dies ist eine experimentelle Funktion und funktioniert möglicherweise nicht in allen Fällen. Es werden nur die Ausdehnungen von Tick-Labels, Achsenbeschriftungen und Titeln geprüft.
Einfaches Beispiel#
Bei der Standard-Achsenpositionierung können der Achsentitel, die Achsenbeschriftungen oder die Tick-Labels manchmal außerhalb des Abbildungsbereichs liegen und somit abgeschnitten werden.
import matplotlib.pyplot as plt
import numpy as np
plt.rcParams['savefig.facecolor'] = "0.8"
def example_plot(ax, fontsize=12):
ax.plot([1, 2])
ax.locator_params(nbins=3)
ax.set_xlabel('x-label', fontsize=fontsize)
ax.set_ylabel('y-label', fontsize=fontsize)
ax.set_title('Title', fontsize=fontsize)
plt.close('all')
fig, ax = plt.subplots()
example_plot(ax, fontsize=24)

Um dies zu verhindern, muss die Position der Achsen angepasst werden. Bei Subplots kann dies manuell durch Anpassung der Subplot-Parameter mit Figure.subplots_adjust erfolgen. Figure.tight_layout erledigt dies automatisch.
fig, ax = plt.subplots()
example_plot(ax, fontsize=24)
plt.tight_layout()

Beachten Sie, dass matplotlib.pyplot.tight_layout() die Subplot-Parameter nur anpasst, wenn es aufgerufen wird. Um diese Anpassung jedes Mal durchzuführen, wenn die Abbildung neu gezeichnet wird, können Sie fig.set_tight_layout(True) aufrufen oder äquivalent rcParams["figure.autolayout"] (Standard: False) auf True setzen.
Wenn Sie mehrere Subplots haben, überschneiden sich oft die Beschriftungen verschiedener Achsen.

tight_layout() passt auch den Abstand zwischen den Subplots an, um die Überlappungen zu minimieren.

tight_layout() kann die Schlüsselwörter pad, w_pad und h_pad übernehmen. Diese steuern den zusätzlichen Abstand um den Abbildungsrand und zwischen den Subplots. Die Abstände werden in Bruchteilen der Schriftgröße angegeben.

tight_layout() funktioniert auch dann, wenn die Größen der Subplots unterschiedlich sind, solange ihre Rasterdefinitionen kompatibel sind. Im folgenden Beispiel sind ax1 und ax2 Subplots eines 2x2-Rasters, während ax3 ein 1x2-Raster ist.
plt.close('all')
fig = plt.figure()
ax1 = plt.subplot(221)
ax2 = plt.subplot(223)
ax3 = plt.subplot(122)
example_plot(ax1)
example_plot(ax2)
example_plot(ax3)
plt.tight_layout()

Es funktioniert mit Subplots, die mit subplot2grid() erstellt wurden. Im Allgemeinen funktionieren Subplots, die aus dem Gridspec erstellt wurden (Anordnung mehrerer Achsen in einer Abbildung).
plt.close('all')
fig = plt.figure()
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)
plt.tight_layout()

Obwohl nicht gründlich getestet, scheint es für Subplots mit aspect != "auto" (z. B. Achsen mit Bildern) zu funktionieren.
arr = np.arange(100).reshape((10, 10))
plt.close('all')
fig = plt.figure(figsize=(5, 4))
ax = plt.subplot()
im = ax.imshow(arr, interpolation="none")
plt.tight_layout()

Einschränkungen#
tight_layoutberücksichtigt standardmäßig alle Künstler auf den Achsen. Um einen Künstler von der Layout-Berechnung auszuschließen, können SieArtist.set_in_layoutaufrufen.tight_layoutgeht davon aus, dass der zusätzliche Platz, der für Künstler benötigt wird, unabhängig vom ursprünglichen Speicherort der Achsen ist. Dies ist oft der Fall, aber es gibt seltene Fälle, in denen dies nicht zutrifft.pad=0kann einige Texte um wenige Pixel abschneiden. Dies kann ein Fehler oder eine Einschränkung des aktuellen Algorithmus sein, und es ist nicht klar, warum es passiert. In der Zwischenzeit wird die Verwendung von pad größer als 0,3 empfohlen.Der Algorithmus von
tight_layoutkonvergiert nicht unbedingt, d. h. mehrmaliges Aufrufen vontight_layoutkann zu leichten Layout-Variationen zwischen den Aufrufen führen.
Verwendung mit GridSpec#
GridSpec hat seine eigene GridSpec.tight_layout Methode (die Pyplot-API pyplot.tight_layout funktioniert ebenfalls).
import matplotlib.gridspec as gridspec
plt.close('all')
fig = plt.figure()
gs1 = gridspec.GridSpec(2, 1)
ax1 = fig.add_subplot(gs1[0])
ax2 = fig.add_subplot(gs1[1])
example_plot(ax1)
example_plot(ax2)
gs1.tight_layout(fig)

Sie können einen optionalen Parameter rect angeben, der die Bounding Box festlegt, in die die Subplots eingepasst werden. Die Koordinaten sind in normalisierten Abbildungskoordinaten und standardmäßig (0, 0, 1, 1) (die gesamte Abbildung).
fig = plt.figure()
gs1 = gridspec.GridSpec(2, 1)
ax1 = fig.add_subplot(gs1[0])
ax2 = fig.add_subplot(gs1[1])
example_plot(ax1)
example_plot(ax2)
gs1.tight_layout(fig, rect=[0, 0, 0.5, 1.0])

Wir empfehlen jedoch nicht, dies zur manuellen Konstruktion komplizierterer Layouts zu verwenden, z. B. ein GridSpec links und ein weiteres rechts in der Abbildung. Für diese Anwendungsfälle sollten Sie stattdessen verschachtelte Gridspecs oder die Abbildungssubfiguren nutzen.
Legenden und Annotationen#
Vor Matplotlib 2.2 wurden Legenden und Annotationen von den Bounding-Box-Berechnungen ausgeschlossen, die das Layout bestimmen. Anschließend wurden diese Künstler in die Berechnung einbezogen, aber manchmal ist es unerwünscht, sie einzubeziehen. Zum Beispiel könnte es in diesem Fall gut sein, dass die Achsen etwas schrumpfen, um Platz für die Legende zu schaffen.
fig, ax = plt.subplots(figsize=(4, 3))
lines = ax.plot(range(10), label='A simple plot')
ax.legend(bbox_to_anchor=(0.7, 0.5), loc='center left',)
fig.tight_layout()
plt.show()

Manchmal ist dies jedoch nicht erwünscht (häufig bei Verwendung von fig.savefig('outname.png', bbox_inches='tight')). Um die Legende aus der Bounding-Box-Berechnung zu entfernen, setzen wir einfach ihre Bounding leg.set_in_layout(False) und die Legende wird ignoriert.
fig, ax = plt.subplots(figsize=(4, 3))
lines = ax.plot(range(10), label='B simple plot')
leg = ax.legend(bbox_to_anchor=(0.7, 0.5), loc='center left',)
leg.set_in_layout(False)
fig.tight_layout()
plt.show()

Verwendung mit AxesGrid1#
Es wird eine eingeschränkte Unterstützung für mpl_toolkits.axes_grid1 bereitgestellt.
from mpl_toolkits.axes_grid1 import Grid
plt.close('all')
fig = plt.figure()
grid = Grid(fig, rect=111, nrows_ncols=(2, 2),
axes_pad=0.25, label_mode='L',
)
for ax in grid:
example_plot(ax)
ax.title.set_visible(False)
plt.tight_layout()

Colorbar#
Wenn Sie eine Colorbar mit Figure.colorbar erstellen, wird die erstellte Colorbar in einem Subplot gezeichnet, solange die Elternachse ebenfalls ein Subplot ist, sodass Figure.tight_layout funktioniert.
plt.close('all')
arr = np.arange(100).reshape((10, 10))
fig = plt.figure(figsize=(4, 4))
im = plt.imshow(arr, interpolation="none")
plt.colorbar(im)
plt.tight_layout()

Eine weitere Möglichkeit ist die Verwendung des AxesGrid1-Toolkits, um explizit eine Achse für die Colorbar zu erstellen.
from mpl_toolkits.axes_grid1 import make_axes_locatable
plt.close('all')
arr = np.arange(100).reshape((10, 10))
fig = plt.figure(figsize=(4, 4))
im = plt.imshow(arr, interpolation="none")
divider = make_axes_locatable(plt.gca())
cax = divider.append_axes("right", "5%", pad="3%")
plt.colorbar(im, cax=cax)
plt.tight_layout()

Gesamtlaufzeit des Skripts: (0 Minuten 8,837 Sekunden)