Legende platzieren ( bbox_to_anchor
)
Eine Legende wird innerhalb des Begrenzungsrahmens der Achsen mit dem loc
Argument to positioniert plt.legend
.
Beispiel loc="upper right"
stellt die Legende in der oberen rechten Ecke des Begrenzungsrahmens, der standardmäßig Ausdehnungen von (0,0)
bis (1,1)
in Achsen - Koordinaten (oder Box - Notation in Bounding (x0,y0, width, height)=(0,0,1,1)
).
Um die Legende außerhalb des Achsenbegrenzungsrahmens zu platzieren, kann ein Tupel (x0,y0)
von Achsenkoordinaten in der unteren linken Ecke der Legende angegeben werden.
plt.legend(loc=(1.04,0))
Ein vielseitigerer Ansatz wäre jedoch, den Begrenzungsrahmen, in den die Legende eingefügt werden soll, mithilfe des bbox_to_anchor
Arguments manuell anzugeben . Man kann sich darauf beschränken, nur den (x0,y0)
Teil der bbox zu liefern. Dadurch wird ein Feld mit einer Spannweite von Null erstellt, aus dem die Legende in die durch das loc
Argument angegebene Richtung erweitert wird . Z.B
plt.legend (bbox_to_anchor = (1.04,1), loc = "oben links")
Platziert die Legende außerhalb der Achsen, sodass sich die obere linke Ecke der Legende (1.04,1)
in Achsenkoordinaten befindet.
Weitere Beispiele sind unten angegeben, wo zusätzlich das Zusammenspiel zwischen verschiedenen Argumenten wie mode
und ncols
gezeigt wird.
l1 = plt.legend(bbox_to_anchor=(1.04,1), borderaxespad=0)
l2 = plt.legend(bbox_to_anchor=(1.04,0), loc="lower left", borderaxespad=0)
l3 = plt.legend(bbox_to_anchor=(1.04,0.5), loc="center left", borderaxespad=0)
l4 = plt.legend(bbox_to_anchor=(0,1.02,1,0.2), loc="lower left",
mode="expand", borderaxespad=0, ncol=3)
l5 = plt.legend(bbox_to_anchor=(1,0), loc="lower right",
bbox_transform=fig.transFigure, ncol=3)
l6 = plt.legend(bbox_to_anchor=(0.4,0.8), loc="upper right")
Details zur Interpretation des 4-Tupel-Arguments bbox_to_anchor
wie in l4
finden Sie in dieser Frage . Das mode="expand"
erweitert die Legende horizontal innerhalb des Begrenzungsrahmens des 4-Tupels. Eine vertikal erweiterte Legende finden Sie in dieser Frage .
Manchmal kann es nützlich sein, den Begrenzungsrahmen in Zahlenkoordinaten anstelle von Achsenkoordinaten anzugeben. Dies wird im l5
obigen Beispiel gezeigt, in dem das bbox_transform
Argument verwendet wird, um die Legende in der unteren linken Ecke der Abbildung zu platzieren.
Nachbearbeitung
Wenn die Legende außerhalb der Achsen platziert wird, führt dies häufig zu der unerwünschten Situation, dass sie sich ganz oder teilweise außerhalb der Leinwand befindet.
Lösungen für dieses Problem sind:
Anpassen der Subplot-Parameter Mit
können Sie die Subplot-Parameter so einstellen, dass die Achsen weniger Platz in der Figur beanspruchen (und dadurch mehr Platz für die Legende lassen) plt.subplots_adjust
. Z.B
plt.subplots_adjust(right=0.7)
Lässt 30% Platz auf der rechten Seite der Figur, wo man die Legende platzieren könnte.
Enges Layout
Verwenden von plt.tight_layout
Ermöglicht das automatische Anpassen der Unterzeichnungsparameter, sodass die Elemente in der Figur eng an den Kanten der Figur anliegen. Leider wird die Legende in diesem Automatismus nicht berücksichtigt, aber wir können ein Rechteckfeld bereitstellen, in das der gesamte Teilplotbereich (einschließlich Beschriftungen) passt.
plt.tight_layout(rect=[0,0,0.75,1])
Speichern der Figur mitbbox_inches = "tight"
Das Argument bbox_inches = "tight"
to plt.savefig
kann verwendet werden, um die Figur so zu speichern, dass alle Künstler auf der Leinwand (einschließlich der Legende) in den gespeicherten Bereich passen. Bei Bedarf wird die Figurengröße automatisch angepasst.
plt.savefig("output.png", bbox_inches="tight")
- Automatisches Anpassen der Subplot-Parameter
Eine Möglichkeit, die Subplot-Position automatisch so anzupassen, dass die Legende in die Leinwand passt, ohne die Figurengröße zu ändern , finden Sie in dieser Antwort: Erstellen einer Figur mit exakter Größe und ohne Polsterung (und Legende außerhalb der Achsen)
Vergleich zwischen den oben diskutierten Fällen:
Alternativen
Eine Figurenlegende
Man kann anstelle der Achsen eine Legende für die Figur verwenden matplotlib.figure.Figure.legend
. Dies ist besonders nützlich für die matplotlib-Version> = 2.1, bei der keine speziellen Argumente erforderlich sind
fig.legend(loc=7)
eine Legende für alle Künstler in den verschiedenen Achsen der Figur zu erstellen. Die Legende wird mit dem loc
Argument platziert, ähnlich wie sie innerhalb einer Achse platziert wird, jedoch in Bezug auf die gesamte Figur - daher befindet sie sich etwas automatisch außerhalb der Achsen. Was bleibt, ist, die Unterzeichnungen so anzupassen, dass es keine Überlappung zwischen der Legende und den Achsen gibt. Hier ist der Punkt "Anpassen der Subplot-Parameter" von oben hilfreich. Ein Beispiel:
import numpy as np
import matplotlib.pyplot as plt
x = np.linspace(0,2*np.pi)
colors=["#7aa0c4","#ca82e1" ,"#8bcd50","#e18882"]
fig, axes = plt.subplots(ncols=2)
for i in range(4):
axes[i//2].plot(x,np.sin(x+i), color=colors[i],label="y=sin(x+{})".format(i))
fig.legend(loc=7)
fig.tight_layout()
fig.subplots_adjust(right=0.75)
plt.show()
Legende in dedizierten Nebenplotachsen
Eine Alternative zur Verwendung besteht bbox_to_anchor
darin, die Legende in ihren dedizierten Unterplotachsen zu platzieren ( lax
). Da das Legendenunterdiagramm kleiner als das Diagramm sein sollte, können wir es gridspec_kw={"width_ratios":[4,1]}
bei der Achsenerstellung verwenden. Wir können die Achsen ausblenden, lax.axis("off")
aber dennoch eine Legende einfügen. Die Legendengriffe und Beschriftungen müssen aus dem realen Plot über abgerufen werden h,l = ax.get_legend_handles_labels()
und können dann der Legende im lax
Unterplot übergeben werden lax.legend(h,l)
. Ein vollständiges Beispiel finden Sie unten.
import matplotlib.pyplot as plt
plt.rcParams["figure.figsize"] = 6,2
fig, (ax,lax) = plt.subplots(ncols=2, gridspec_kw={"width_ratios":[4,1]})
ax.plot(x,y, label="y=sin(x)")
....
h,l = ax.get_legend_handles_labels()
lax.legend(h,l, borderaxespad=0)
lax.axis("off")
plt.tight_layout()
plt.show()
Dies erzeugt eine Handlung, die der Handlung von oben optisch ziemlich ähnlich ist:
Wir könnten auch die ersten Achsen verwenden, um die Legende zu platzieren, aber die bbox_transform
der Legendenachsen verwenden,
ax.legend(bbox_to_anchor=(0,0,1,1), bbox_transform=lax.transAxes)
lax.axis("off")
Bei diesem Ansatz müssen wir die Legendenhandles nicht extern abrufen, sondern das bbox_to_anchor
Argument angeben .
Weiterführende Literatur und Hinweise:
- Betrachten Sie den Matplotlib- Legendenführer mit einigen Beispielen für andere Dinge , die Sie mit Legenden tun möchten.
- Ein Beispielcode zum Platzieren von Legenden für Kreisdiagramme kann direkt als Antwort auf diese Frage gefunden werden: Python - Legende überschneidet sich mit dem Kreisdiagramm
- Das
loc
Argument kann Zahlen anstelle von Zeichenfolgen annehmen, wodurch Aufrufe kürzer werden. Sie sind jedoch nicht sehr intuitiv aufeinander abgestimmt. Hier ist das Mapping als Referenz: