Ich habe eine Reihe von 20 Plots (keine Unterplots), die in einer einzigen Figur erstellt werden sollen. Ich möchte, dass die Legende außerhalb des Rahmens liegt. Gleichzeitig möchte ich die Achsen nicht ändern, da die Größe der Figur reduziert wird. Bitte helfen Sie mir bei folgenden Fragen:
- Ich möchte das Legendenfeld außerhalb des Handlungsbereichs halten. (Ich möchte, dass sich die Legende draußen auf der rechten Seite des Handlungsbereichs befindet.)
- Gibt es sowieso, dass ich die Schriftgröße des Textes innerhalb des Legendenfeldes reduziere, so dass die Größe des Legendenfeldes klein wird.
python
matplotlib
legend
pottigopi
quelle
quelle
https://stackoverflow.com/a/43439132/52074
. und das mit zwei Codezeilen! Die +1200 upvoted Antwort ist auch gut, aber ich fand es weniger generisch.Antworten:
Sie können den Legendentext verkleinern, indem Sie Schrifteigenschaften erstellen:
quelle
plot1
in dieser Antwort?legend
in dieser Antwort?plt.legend(fontsize='small')
Es gibt verschiedene Möglichkeiten, das zu tun, was Sie wollen. Um das zu ergänzen, was @inalis und @Navi bereits gesagt haben, können Sie das
bbox_to_anchor
Schlüsselwortargument verwenden, um die Legende teilweise außerhalb der Achsen zu platzieren und / oder die Schriftgröße zu verringern.Versuchen Sie, die Legende an verschiedenen Stellen zu platzieren, bevor Sie die Schriftgröße verringern (was das Lesen erheblich erschwert).
Beginnen wir also mit einem allgemeinen Beispiel:
Wenn wir dasselbe tun, aber das
bbox_to_anchor
Schlüsselwortargument verwenden, können wir die Legende leicht außerhalb der Achsengrenzen verschieben:Ebenso können Sie die Legende horizontaler gestalten und / oder oben in die Figur einfügen (ich drehe auch abgerundete Ecken und einen einfachen Schlagschatten an):
Alternativ können Sie die Breite des aktuellen Diagramms verkleinern und die Legende vollständig außerhalb der Achse der Figur platzieren (Hinweis: Wenn Sie tight_layout () verwenden , lassen Sie ax.set_position () weg:
Auf ähnliche Weise können Sie das Diagramm vertikal verkleinern und die horizontale Legende unten einfügen:
Schauen Sie sich den Matplotlib-Legendenführer an . Sie könnten auch einen Blick darauf werfen
plt.figlegend()
.quelle
bbox_to_anchor
ein Tupel von 4 Gleitkommazahlen (x, y, Breite, Höhe der bbox) oder ein Tupel von 2 Gleitkommazahlen (x, y) in normalisierten Achsen ist Koordinaten. "legend = ax.legend()
und späterfig.savefig(bbox_extra_artists=(legend,))
Legende platzieren (
bbox_to_anchor
)Eine Legende wird innerhalb des Begrenzungsrahmens der Achsen mit dem
loc
Argument to positioniertplt.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.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 dasloc
Argument angegebene Richtung erweitert wird . Z.BPlatziert 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
undncols
gezeigt wird.Details zur Interpretation des 4-Tupel-Arguments
bbox_to_anchor
wie inl4
finden Sie in dieser Frage . Dasmode="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 dasbbox_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.BLä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.Speichern der Figur mit
bbox_inches = "tight"
Das Argument
bbox_inches = "tight"
toplt.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.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 sindeine 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: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 esgridspec_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 werdenh,l = ax.get_legend_handles_labels()
und können dann der Legende imlax
Unterplot übergeben werdenlax.legend(h,l)
. Ein vollständiges Beispiel finden Sie unten.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,Bei diesem Ansatz müssen wir die Legendenhandles nicht extern abrufen, sondern das
bbox_to_anchor
Argument angeben .Weiterführende Literatur und Hinweise:
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:quelle
fig.tight_layout
. Wenn Sieplt.subplots
zum Erstellen der Achsen verwenden, geben Sie einfach so etwas wiegridspec_kw={'height_ratios': [100, 1]}
(oder width_ratios) ein, damit die Achsen der Legende winzig sind ... Dannfig.tight_layout()
wird es entsprechend erweitert. Zumindest für matplotlib 3.0.3.Rufen Sie einfach
legend()
nach demplot()
Anruf wie folgt an:Die Ergebnisse würden ungefähr so aussehen:
quelle
Verwenden Sie
loc
undbbox_to_anchor
Schlüsselwörter von , um die Legende außerhalb des Plotbereichs zu platzierenlegend()
. Mit dem folgenden Code wird die Legende beispielsweise rechts vom Plotbereich platziert:Weitere Informationen finden Sie im Legendenhandbuch
quelle
plt.tight_layout()
?Kurze Antwort: Sie können
bbox_to_anchor
+bbox_extra_artists
+ verwendenbbox_inches='tight'
.Längere Antwort: Sie können
bbox_to_anchor
die Position des Legendenfelds manuell angeben, wie einige andere Personen in den Antworten ausgeführt haben.Das übliche Problem ist jedoch, dass das Legendenfeld beschnitten ist, z.
Um zu verhindern, dass das Legendenfeld beschnitten wird, können Sie beim Speichern der Figur die Parameter verwenden
bbox_extra_artists
undbbox_inches
fragensavefig
, ob beschnittene Elemente in das gespeicherte Bild aufgenommen werden sollen:fig.savefig('image_output.png', bbox_extra_artists=(lgd,), bbox_inches='tight')
Beispiel (Ich habe nur die letzte Zeile geändert, um 2 Parameter hinzuzufügen
fig.savefig()
):Ich wünschte, Matplotlib würde nativ einen externen Standort für die Legendenbox zulassen, wie es Matlab tut :
quelle
bbox_inches='tight'
funktioniert aber auch ohne bbox_extra_artistZusätzlich zu all den hervorragenden Antworten hier, neuere Versionen
matplotlib
undpylab
kann automatisch bestimmen , wo die Legende zu setzen , ohne mit den Stellplätzen zu stören , wenn möglich.Dadurch wird die Legende nach Möglichkeit automatisch von den Daten entfernt!
Wenn es jedoch keinen Platz gibt, an dem die Legende platziert werden kann, ohne die Daten zu überlappen, sollten Sie eine der anderen Antworten ausprobieren. Mit using
loc="best"
wird die Legende niemals außerhalb der Handlung platziert.quelle
Kurze Antwort : Rufen Sie Draggable für die Legende auf und verschieben Sie sie interaktiv, wo immer Sie möchten:
Lange Antwort : Wenn Sie die Legende lieber interaktiv / manuell als programmgesteuert platzieren möchten, können Sie den ziehbaren Modus der Legende so umschalten, dass Sie sie an eine beliebige Stelle ziehen können. Überprüfen Sie das folgende Beispiel:
quelle
Nicht genau das, wonach Sie gefragt haben, aber ich fand, dass es eine Alternative für das gleiche Problem ist. Machen Sie die Legende halbtransparent wie folgt:
Tun Sie dies mit:
quelle
Wie bereits erwähnt, können Sie die Legende auch im Plot oder leicht vom Rand entfernt platzieren. Hier ist ein Beispiel für die Verwendung der Plotly Python-API , die mit einem IPython-Notizbuch erstellt wurde . Ich bin im Team.
Zunächst möchten Sie die erforderlichen Pakete installieren:
Installieren Sie dann Plotly:
Dadurch wird Ihr Diagramm erstellt und Sie können die Legende im Diagramm selbst behalten. Wenn die Legende nicht festgelegt ist, wird sie standardmäßig im Diagramm platziert, wie hier gezeigt.
Für eine alternative Platzierung können Sie den Rand des Diagramms und den Rand der Legende eng ausrichten und Randlinien für eine engere Anpassung entfernen.
Sie können die Legende und das Diagramm mit Code oder über die GUI verschieben und neu formatieren. Um die Legende zu verschieben, haben Sie die folgenden Optionen, um die Legende innerhalb des Diagramms zu positionieren, indem Sie x- und y-Werte von <= 1 zuweisen. Beispiel:
{"x" : 0,"y" : 0}
-- Unten links{"x" : 1, "y" : 0}
-- Unten rechts{"x" : 1, "y" : 1}
-- Oben rechts{"x" : 0, "y" : 1}
-- Oben links{"x" :.5, "y" : 0}
-- Unten in der Mitte{"x": .5, "y" : 1}
-- Oben in der MitteIn diesem Fall wählen wir oben rechts
legendstyle = {"x" : 1, "y" : 1}
, ebenfalls in der Dokumentation beschrieben :quelle
Etwas in dieser Richtung hat bei mir funktioniert. Ausgehend von einem Code von Joe ändert diese Methode die Fensterbreite, um automatisch eine Legende rechts von der Abbildung anzupassen.
quelle
mgr.window.wm_geometry(...)
durchmgr.window.setFixedWidth(winWidthNew)
.fig.set_size_inches(...)
kümmert sich um die Größenänderung, die Sie benötigen.Es lohnt sich, diese Frage zu aktualisieren, da neuere Versionen von Matplotlib es viel einfacher gemacht haben, die Legende außerhalb der Handlung zu positionieren. Ich habe dieses Beispiel mit der Matplotlib-Version erstellt
3.1.1
.Benutzer können dem
loc
Parameter ein 2-Tupel von Koordinaten übergeben, um die Legende an einer beliebigen Stelle im Begrenzungsrahmen zu positionieren. Das einzige Problem ist, dass Sie ausführen müssenplt.tight_layout()
, damit matplotlib die Plotdimensionen neu berechnet, sodass die Legende sichtbar ist:Dies führt zu folgendem Plot:
Verweise:
quelle
Sie können es auch versuchen
figlegend
. Es ist möglich, eine Legende unabhängig von einem beliebigen Axes-Objekt zu erstellen. Möglicherweise müssen Sie jedoch einige "Dummy" -Pfade erstellen, um sicherzustellen, dass die Formatierung für die Objekte korrekt weitergegeben wird.quelle
Hier ist ein Beispiel aus dem matplotlib tutorial hier . Dies ist eines der einfacheren Beispiele, aber ich habe der Legende Transparenz hinzugefügt und plt.show () hinzugefügt, damit Sie dies in die interaktive Shell einfügen und ein Ergebnis erhalten können:
quelle
Die Lösung, die für mich funktionierte, als ich eine große Legende hatte, bestand darin, ein extra leeres Bildlayout zu verwenden. Im folgenden Beispiel habe ich 4 Zeilen erstellt und unten zeichne ich ein Bild mit einem Versatz für die Legende (bbox_to_anchor) oben, es wird nicht geschnitten.
quelle
Hier ist eine andere Lösung, ähnlich wie beim Hinzufügen von
bbox_extra_artists
undbbox_inches
, bei der Sie keine zusätzlichen Künstler im Rahmen Ihrer haben müssensavefig
Anrufs haben müssen. Ich habe mir das ausgedacht, da ich den größten Teil meiner Handlung innerhalb von Funktionen generiere.Anstatt alle Ihre Ergänzungen zum Begrenzungsrahmen hinzuzufügen, wenn Sie sie ausschreiben möchten, können Sie sie den
Figure
Künstlern des Künstlers vorab hinzufügen . Verwenden Sie etwas Ähnliches wie die Antwort von Franck Dernoncourt oben :Hier ist das generierte Diagramm.
quelle
Ich weiß nicht, ob Sie Ihr Problem bereits gelöst haben ... wahrscheinlich ja, aber ... Ich habe einfach die Zeichenfolge 'außerhalb' für den Speicherort verwendet, wie in matlab. Ich habe Pylab aus Matplotlib importiert. Sehen Sie den Code wie folgt:
Klicken Sie hier, um das Diagramm anzuzeigen
quelle