2016-06-14 12 views
2

Ich möchte die Seaborn-Paarplot-Legende außerhalb der Streudiagramm-Matrix verschieben. Die offizielle docs geben kein Stichwort legend. Ich versuche, die Legende außerhalb des Diagramms in 3 verschiedenen Orten gleichzeitig zu zeichnen: unten in der Mitte, oben in der Mitte, rechts MitteSeaborn pairplot legende - wie man die Position steuert

Ich habe versucht, dies:

import matplotlib.pyplot as plt 
import seaborn as sns 
iris = sns.load_dataset("iris") 
g = sns.pairplot(iris,hue='species', palette='husl', markers='d', size=2.5, plot_kws= 
    { 
    "s":40, 
    "alpha":1.0, 
    'lw':0.5, 
    'edgecolor':'k' 
    }) 
plt.legend(loc='upper center', bbox_to_anchor=(1.10, 1.0), ncol=1) #vertical legend 
plt.legend(loc='lower center', bbox_to_anchor=(0.0, -0.15), ncol=3) #horizontal legend bottom 
plt.legend(loc='upper left', bbox_to_anchor=(0.0, 1.15), ncol=3) #horizontal legend top 
g.savefig('Test.png', bbox_inches='tight') 

Die Ausgabe des obigen Codes ist diese Datei: output file.

Alle 3 Legenden werden falsch gedruckt. Ich bin mir nicht sicher, ob es die Positionierung tut, die ich angefordert habe. Ich bin mir nicht sicher, was rechts passiert - es scheint, dass 2 vertikale Legenden erscheinen und aus irgendeinem Grund und sie sich vollständig überlappen. Eine der beiden horizontalen Legenden erscheint überhaupt nicht.

Gibt es eine Möglichkeit, die vertikalen Legenden nicht zu überlappen und die Legende auch an drei Stellen außerhalb des Diagramms zu platzieren - oben Mitte, unten Mitte, rechts Mitte?

+0

Der Standardstandort ist senkrecht nach rechts ausgerichtet, wie hier [http://stackoverflow.com/questions/32244753/how-to-save-a-seaborn-plot-into-a-file] zu sehen ist. Aber es muss eine Möglichkeit geben, die Legende an einem dieser 3 Orte zu zeichnen. Irgendwelche Vorschläge hier? –

Antwort

4

pairplot fügt bereits eine Legende außerhalb der Plot Matrix und es ist nicht klar, wo Sie es verschieben möchten. Die anderen Legenden werden wahrscheinlich so positioniert, wie Sie es gewünscht haben, auch wenn das nicht das ist, was Sie wirklich wollen.

plt.legend wird eine Legende an die aktuellen Achsen angehängt und es kann nur eine Legende pro Achse geben, so dass in Ihrem Code nur die letzte Legende gezeichnet wird. Aber Sie können mehrere Legenden an eine Figur und an IIUC anhängen, um die Legenden relativ zur Figur zu positionieren, sodass Figurenlegenden als die beste Option erscheinen.

Um Figurenlegenden zu zeichnen, müssen Sie die Handler und Beschriftungen explizit übergeben. Ich musste das private Attribut PairPlot._legend_data dafür verwenden, ich habe keinen Weg gefunden, es mit der öffentlichen API zu tun.

Leider wird Matplotlib nicht automatisch Platz schaffen, um diese Legenden zu akomodieren, und sie werden sich mit den Teilplots überschneiden, wenn Sie nicht einige Anpassungen vornehmen. Ich werde einfach subplot_adjust mit einigen hartcodierten Werten verwenden, die für mich in diesem Fall funktionieren, weil Berechnungen schwierig sind.

Also das ist der Code, der hoffentlich tut, was Sie wollen:

g = sns.pairplot(iris, hue='species', palette='husl', markers='d', size=2.5, plot_kws= 
    { 
    "s":40, 
    "alpha":1.0, 
    'lw':0.5, 
    'edgecolor':'k' 
    }) 

handles = g._legend_data.values() 
labels = g._legend_data.keys() 
g.fig.legend(handles=handles, labels=labels, loc='upper center', ncol=1) 
g.fig.legend(handles=handles, labels=labels, loc='lower center', ncol=3) 
g.fig.legend(handles=handles, labels=labels, loc='upper left', ncol=3) 
g.fig.subplots_adjust(top=0.92, bottom=0.08) 

pairplot

Die OP in einem Kommentar gefragt, ob dies in der Seaborn Dokumentation zu finden sind. Natürlich gehört dazu auch reines Matplotlib, nicht spezifisch für Seabohnen. Aber ich erkannte auch, dass ich mich auf ein paar undokumentierte Funktionen verlassen musste.

Die Tatsache, dass PairGrid ein fig Attribut hat, das auf die Figure Instanz verweist, ist nicht dokumentiert. Wie auch immer, das war eine einfache Schätzung und ich hätte stattdessen fig = plt.gcf() verwenden können.

Das Finden der Beschriftungen und Griffe der Legende ist komplizierter. Ich habe über das _legend_data Attribut durch Blick auf die Docstring von PairGrid.add_legend gelernt, aber der Docstring selbst ist ein wenig versteckt (es erscheint nicht im Web) und das Attribut ist unterstrichen, als ob es privat wäre, so dass es sich unwohl fühlt. Ich finde es inkonsistent, dass ein privates Attribut im Docstring einer öffentlichen Methode erwähnt wird, wahrscheinlich sollten wir legend_data als öffentliches Attribut haben, aber ich schweife ab.

Alternativ könnten Sie versuchen, die Beschriftungen und Handles aus den Teilplots zu extrahieren. Sie können vermuten, dass die Subplots diese Informationen haben, aber es gibt keine tatsächlichen Garantien, also bedeutet dies, auf undokumentiertes Verhalten zu vertrauen. Es stellt sich heraus, dass die nicht-diagonalen Subplots es haben (aber die diagonalen Subplots haben es nicht, also, wenn Sie nur auf den ersten Subplot geschaut hätten, wären Sie fehlgeleitet) und Sie können handles, labels = fig.get_axes()[1].get_legend_handles_labels() tun. Aber wie gesagt, dies ist undokumentiertes Verhalten, selbst wenn Sie nur dokumentierte API verwenden.

Sie könnten auch Ihre eigenen Handles erstellen, aber es wäre umständlich, deshalb habe ich nach Shortcuts gesucht, auch wenn undokumentiert.

+0

Danke! Dies ist die Antwort auf die Frage. Hast du das in der Seaborn-Dokumentation gefunden? –

+1

@WR Ich habe die Antwort bearbeitet, lassen Sie mich wissen, wenn ich Ihre Bedenken nicht angesprochen habe. – Goyo

+0

Fertig. Guter Eintrag! Keine weiteren Fragen von mir zu dieser Frage. Vielen Dank, @ Goyo! –

3

Das ist eigentlich viel einfacher als Sie denken, dass es ist. Es ist einfach eine Standardeinstellung in der tatsächlichen Matplot-Ausgabe. Gehen Sie einfach zur Schaltfläche configure subplot am oberen Rand des Ausgabefensters, und senken Sie die obere Grenze des rechten Rands ein wenig ab und es wird behoben.

Example with button to click circled

+0

Oh, ich sehe, dass Sie zuerst eine Python-Figur erstellen, dann die Legendenposition festlegen und sie dann in einem Bild speichern. Sie sagen also, dass es keine programmgesteuerte Einstellung gibt? –

+0

Ja, ich konnte nicht finden. Das Problem ist, dass Matplot es nicht als Tabelle erkennt. Ich nehme an, du könntest in das Paarplot-Skript einsteigen und sehen, ob du damit herumhantieren willst, aber ich denke nicht, dass es in der Art editierbar ist, wie du es (und ich) ursprünglich versucht hast. Ich habe das gleiche Thema auf GitHub gesehen und auch niemand hat es herausgefunden. – natelacombe

Verwandte Themen