Skip to content
Themen
Matplotlib
Matplotlib Legende außerhalb des Plots: bbox_to_anchor Cheatsheet

Matplotlib Legende außerhalb des Plots: bbox_to_anchor Cheatsheet

Veröffentlicht am

Aktualisiert am

Legende in Matplotlib mit bbox_to_anchor und loc außerhalb der Achsen platzieren — rechts, links oder unter dem Plot. Achsen verkleinern und mit bbox_inches='tight' ohne Abschneiden exportieren.

Standard-Legenden sitzen innerhalb der Achsen und verdecken oft Daten. Um die Legende außerhalb zu parken, loc (welche Ecke der Legendenbox der Anker ist) mit bbox_to_anchor (wo dieser Anker in Achsenkoordinaten liegt) kombinieren.

Schnelle Lösung

import matplotlib.pyplot as plt
import numpy as np
 
x = np.linspace(0, 10, 200)
fig, ax = plt.subplots()
ax.plot(x, np.sin(x), label="sin(x)")
ax.plot(x, np.cos(x), label="cos(x)")
 
# Outside, upper-right of the axes
ax.legend(bbox_to_anchor=(1.02, 1), loc="upper left", borderaxespad=0)
 
plt.tight_layout()
plt.show()
PlatzierungTypischer Aufruf
Rechts der Achsenlegend(bbox_to_anchor=(1.02, 1), loc="upper left")
Rechts, vertikal zentriertlegend(loc="center left", bbox_to_anchor=(1.02, 0.5))
Unten, horizontallegend(loc="upper center", bbox_to_anchor=(0.5, -0.12), ncol=n)
Obenlegend(loc="lower center", bbox_to_anchor=(0.5, 1.02), ncol=n)
Export ohne Abschneidensavefig(..., bbox_inches="tight") oder tight_layout() / constrained_layout=True

Achsenkoordinaten: (0, 0) ist die untere linke Ecke der Axes, (1, 1) die obere rechte. Werte leicht über 1 oder unter 0 liegen knapp außerhalb des Plot-Rahmens.

Das Problem: Legende über den Daten

fig, ax = plt.subplots(figsize=(7, 4))
ax.plot(x, np.sin(x), label="sin(x)", lw=2)
ax.plot(x, np.cos(x), label="cos(x)", lw=2)
ax.legend(loc="best")  # still inside the axes
ax.set_title("Default legend (often overlaps data)")
plt.show()

Default Matplotlib legend inside the axes

loc="best" wählt nur die am wenigsten schlechte innere Ecke. Die Legende wandert nie in den Figure-Rand.

Wie bbox_to_anchor und loc zusammenwirken

  1. bbox_to_anchor=(x, y) — Punkt in Achsen-Bruchteilen (Standard).
  2. loc="upper left" (usw.) — welcher Punkt der Legendenbox an diesem Anker festgemacht wird.
  3. borderaxespad — Abstand zwischen Axes und Legende; auf 0 setzen für knappes Parken außen.

Denkmodell: Ankerpunkt am Plot + welche Ecke der Legende auf diesem Punkt sitzt.

Legende rechts platzieren

fig, ax = plt.subplots(figsize=(7, 4))
ax.plot(x, np.sin(x), label="sin(x)", lw=2)
ax.plot(x, np.cos(x), label="cos(x)", lw=2)
ax.legend(bbox_to_anchor=(1.02, 1), loc="upper left", borderaxespad=0)
ax.set_title("Legend outside: upper right of axes")
fig.tight_layout()
plt.show()

Legend placed outside to the right of the axes

Schneidet das Fenster die Legende noch ab, tight_layout() aufrufen / constrained_layout=True in subplots nutzen oder Platz schaffen, indem die Axes verkleinert werden (nächster Abschnitt).

Axes verkleinern, dann Legende andocken

Bei vielen Serien dem Plot eine eigene Legenden-Spalte geben:

x = np.arange(10)
fig = plt.figure(figsize=(7.2, 4.2))
ax = fig.add_subplot(111)
 
for i in range(5):
    ax.plot(x, i * x, label=f"y = {i}x", lw=2)
 
# Leave ~22% of the figure width for the legend
box = ax.get_position()
ax.set_position([box.x0, box.y0, box.width * 0.78, box.height])
ax.legend(loc="center left", bbox_to_anchor=(1.02, 0.5), borderaxespad=0)
ax.set_title("Shrink axes, legend to the right")
plt.show()

Axes shrunk with legend docked on the right

Moderne Alternative: Figure mit Layout-Engines erzeugen, die besser mit Künstlern außerhalb der Axes kooperieren:

fig, ax = plt.subplots(layout="constrained")
# ... plot ...
ax.legend(bbox_to_anchor=(1.02, 1), loc="upper left")

Legende unter dem Plot (horizontal)

Mit ncol sitzen die Einträge in einer Reihe unter dem Chart — gut für Folien und breite Dashboards:

x = np.arange(10)
fig = plt.figure(figsize=(7.2, 4.4))
ax = fig.add_subplot(111)
 
for i in range(5):
    ax.plot(x, i * x, label=f"y = {i}x", lw=2)
 
box = ax.get_position()
ax.set_position([box.x0, box.y0 + box.height * 0.12, box.width, box.height * 0.88])
ax.legend(loc="upper center", bbox_to_anchor=(0.5, -0.12), ncol=5)
ax.set_title("Horizontal legend below the plot")
plt.show()

Horizontal legend placed below the plot

Entscheidungsleitfaden

SituationBevorzugen
2–4 Serien, einfaches Liniendiagrammbbox_to_anchor=(1.02, 1), loc="upper left" + tight_layout()
Viele Serien, stabiles LayoutAxes verkleinern / layout="constrained" + rechte Legende
Breite Figure / Präsentationuntere Legende mit ncol
Karte/Bild, bei dem jede Box störthalbtransparente innere Legende: framealpha=0.3 (Kompromiss)
PNG/PDF für Papers speichernimmer bbox_inches="tight" testen (unten)

Export-Falle: Außenlegende fehlt in der Datei

Im interaktiven Fenster kann die Legende sichtbar sein, während savefig sie abschneidet. Der übliche Fix:

fig, ax = plt.subplots(figsize=(7, 4))
ax.plot(x, np.sin(x), label="sin(x)", lw=2)
ax.plot(x, np.cos(x), label="cos(x)", lw=2)
ax.legend(bbox_to_anchor=(1.02, 1), loc="upper left", borderaxespad=0)
ax.set_title("Outside legend kept with bbox_inches='tight'")
 
fig.savefig("legend-outside.png", dpi=150, bbox_inches="tight", facecolor="white")

Saved figure that keeps the outside legend via bbox_inches tight

Verwandter Deep Dive: savefig schneidet Labels ab. Kollidieren Labels weiterhin, die Figure-Größe erhöhen, bevor man Anker-Koordinaten feinjustiert.

Extra-Steuerung (ohne die Box zu verschieben)

ax.legend(
    bbox_to_anchor=(1.02, 1),
    loc="upper left",
    borderaxespad=0,
    frameon=True,
    fancybox=False,
    framealpha=0.95,
    fontsize=9,          # or prop={"size": 9}
    title="Series",
    alignment="left",
)
  • ncol — mehrspaltige Legende
  • framealpha — Transparenz, wenn die Legende über Daten bleiben muss
  • title — Gruppenlabel bei Multi-Serien-Charts

Für allgemeines Legend-Styling (nicht nur Position) siehe Matplotlib Legend.

Typische Fallen

FalleWas man siehtFix
Nur loc="right" gesetztLegende bleibt innenbbox_to_anchor jenseits von 1.0 nötig
Außenlegende in der GUI, fehlt im PNGbeschnittener Exportbbox_inches="tight" oder constrained layout
bbox_to_anchor versehentlich in DatenkoordinatenLegende fliegt wegStandard sind Achsenkoordinaten; 2-Tupel übergeben, kein Bbox, außer absichtlich
Riesige Legendenschriftdominiert die Figurefontsize=8–10 oder weniger Spalten
Überlappung mit Colorbargequetschter RandPlatz für beides reservieren oder Legende nach unten

FAQ

Fazit

Außenlegenden sind ein Layout-Problem, keine geheimnisvolle API: eine Legendenecke mit loc anpinnen, diesen Pin mit bbox_to_anchor knapp jenseits der Axes setzen (> 1 oder < 0), und beim Export tight/constrained Layout nutzen, damit der Rand in der Datei erhalten bleibt. Bei vielen Serien einen rechten Stapel, bei breiten Figures eine untere ncol-Reihe.

Verwandte Anleitungen