Hinweis
Zum Ende springen, um den vollständigen Beispielcode herunterzuladen.
Programmatische Steuerung der Subplot-Anpassung#
Hinweis
Dieses Beispiel soll in erster Linie einige fortgeschrittene Konzepte in Matplotlib zeigen.
Wenn Sie nur nach ausreichend Platz für Ihre Beschriftungen suchen, ist es fast immer einfacher und ausreichend, die Subplot-Parameter entweder manuell mit Figure.subplots_adjust festzulegen oder einen der automatischen Layout-Mechanismen zu verwenden (Leitfaden für eingeschränkte Layouts oder Leitfaden für straffe Layouts).
Dieses Beispiel beschreibt eine benutzerdefinierte Methode, um die Größen von Künstlern auszulesen und die Subplot-Parameter entsprechend einzustellen. Sein Hauptzweck ist es, einige fortgeschrittene Konzepte wie das Auslesen von Textpositionen, die Arbeit mit Bounding Boxes und Transformationen sowie die Verwendung von Events zu veranschaulichen. Es kann aber auch als Ausgangspunkt dienen, wenn Sie das Layout automatisieren möchten und mehr Flexibilität als bei Tight Layout und Constrained Layout benötigen.
Unten sammeln wir die Bounding Boxes aller y-Achsen-Beschriftungen und verschieben den linken Rand des Subplots nach rechts, sodass genügend Platz für die Vereinigung aller Bounding Boxes bleibt.
Es gibt einen Haken bei der Berechnung von Text-Bounding-Boxes: Das Abfragen der Text-Bounding-Boxes (Text.get_window_extent) benötigt einen Renderer (RendererBase-Instanz), um die Textgröße zu berechnen. Dieser Renderer ist erst verfügbar, nachdem die Abbildung gezeichnet wurde (Figure.draw).
Eine Lösung dafür ist, die Anpassungslogik in einen Draw-Callback zu legen. Diese Funktion wird ausgeführt, nachdem die Abbildung gezeichnet wurde. Sie kann nun prüfen, ob der Subplot genügend Platz für den Text lässt. Wenn nicht, werden die Subplot-Parameter aktualisiert und ein zweiter Draw ausgelöst.
import matplotlib.pyplot as plt
import matplotlib.transforms as mtransforms
fig, ax = plt.subplots()
ax.plot(range(10))
ax.set_yticks([2, 5, 7], labels=['really, really, really', 'long', 'labels'])
def on_draw(event):
bboxes = []
for label in ax.get_yticklabels():
# Bounding box in pixels
bbox_px = label.get_window_extent()
# Transform to relative figure coordinates. This is the inverse of
# transFigure.
bbox_fig = bbox_px.transformed(fig.transFigure.inverted())
bboxes.append(bbox_fig)
# the bbox that bounds all the bboxes, again in relative figure coords
bbox = mtransforms.Bbox.union(bboxes)
if fig.subplotpars.left < bbox.width:
# Move the subplot left edge more to the right
fig.subplots_adjust(left=1.1*bbox.width) # pad a little
fig.canvas.draw()
fig.canvas.mpl_connect('draw_event', on_draw)
plt.show()

Referenzen
Die Verwendung der folgenden Funktionen, Methoden, Klassen und Module wird in diesem Beispiel gezeigt