Subplot-Anpassung programmgesteuert steuern #

Notiz

Dieses Beispiel soll in erster Linie einige fortgeschrittene Konzepte in Matplotlib zeigen.

Wenn Sie nur genügend Platz für Ihre Etiketten suchen, ist es fast immer einfacher und gut genug, entweder die Subplot-Parameter manuell mit einzustellen Figure.subplots_adjustoder einen der automatischen Layoutmechanismen zu verwenden ( Constrained Layout Guide oder Tight Layout Guide ).

Dieses Beispiel beschreibt eine benutzerdefinierte Möglichkeit, Künstlergrößen auszulesen und die Subplot-Parameter entsprechend einzustellen. Sein Hauptzweck besteht darin, einige fortgeschrittene Konzepte wie das Auslesen von Textpositionen, das Arbeiten mit Begrenzungsrahmen und Transformationen und die Verwendung von Ereignissen zu veranschaulichen . Es kann aber auch als Ausgangspunkt dienen, wenn Sie das Layout automatisieren möchten und mehr Flexibilität als ein enges Layout und ein eingeschränktes Layout benötigen.

Unten sammeln wir die Bounding Boxes aller y-Labels und verschieben die linke Grenze des Subplots nach rechts, sodass genügend Platz für die Vereinigung aller Bounding Boxes bleibt.

Es gibt einen Haken bei der Berechnung von Textbegrenzungsrahmen: Die Abfrage der Textbegrenzungsrahmen ( Text.get_window_extent) benötigt einen Renderer ( RendererBaseInstanz), um die Textgröße zu berechnen. Dieser Renderer ist erst verfügbar, nachdem die Figur gezeichnet wurde ( Figure.draw).

Eine Lösung hierfür besteht darin, die Anpassungslogik in einen Draw-Callback einzufügen. Diese Funktion wird ausgeführt, nachdem die Figur gezeichnet wurde. Es kann nun prüfen, ob der Subplot genug Platz für den Text lässt. Wenn nicht, werden die Subplot-Parameter aktualisiert und die zweite Ziehung wird 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()
Automatische Nebenhandlungen anpassen

Galerie generiert von Sphinx-Gallery