2016-06-14 165 views
2

我想將Seaborn對圖圖例移到散點圖矩陣之外。官方docs不給關鍵字legend。我想要繪製在同時3個不同位置的情節外傳說:底部中心,頂部中央,Seaborn pairplot圖例 - 如何控制位置

我曾嘗試這一權利中心:

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') 

上述代碼的輸出是這樣的文件: output file

所有3個圖例都打印錯誤。我不確定它是否在做我要求的定位。我不確定右側發生了什麼 - 似乎有2個垂直傳奇正在出現,並且出於某種原因,它們彼此完全重疊。兩個橫向傳奇中的一個根本沒有出現。

有沒有辦法避免重疊垂直的傳說,並將圖例放置在3個位置 - 頂部中心,底部中心,右中心?

+0

默認位置是在右側外部垂直定位的,如[見這裏](http://stackoverflow.com/questions/32244753/how-to-save-a-seaborn-plot-into-a-file)。但是,必須有一種方法來在這三個位置之一上繪製圖例。這裏有什麼建議? –

回答

4

pairplot已經增加了情節矩陣外的傳奇人物,要移動它目前尚不清楚。其他傳說可能正按您的要求定位,即使這可能不是您真正想要的。

plt.legend會將一個圖例附加到當前座標軸上,每個座標軸只能有一個圖例,因此在您的代碼中只繪製了最後一個圖例。但是你可以附加幾個傳說給一個人物和IIUC你想定位的傳說相對於這個數字,所以圖傳說似乎是最好的選擇。

爲了繪製圖例,您需要明確地傳遞處理程序和標籤。我不得不使用私有屬性PairPlot._legend_data,我沒有找到使用公共API的方法。

不幸的是,matplotlib不會自動給這些圖例留出空間,它們會與子圖重疊,除非您進行一些調整。我只是使用subplot_adjust以及一些硬編碼值,這些值在我的情況下適用於這種情況,因爲計算非常棘手。

所以這是代碼,希望你想要做什麼:

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

在評論問的OP,這是否可以seaborn文檔中找到。當然,這只是純matplotlib的一部分,並非特定於seaborn。但我也意識到,我不得不依賴一些無證的功能。

PairGrid具有引用Figure實例的fig屬性的事實未記錄在案。無論如何,這是一個簡單的猜測,我可以用fig = plt.gcf()來代替。

獲取圖例的標籤和句柄比較麻煩。我通過查看PairGrid.add_legend的文檔字符串瞭解了_legend_data屬性,但是文檔字符串本身有點隱藏(它不會出現在網絡中),並且該屬性被強調爲好像它是私人的,所以使用它會感覺不舒服。我發現在公共方法的文檔字符串中提到私有屬性是不一致的,可能我們應該有legend_data作爲公共屬性,但我離題了。

或者,您可以嘗試從子圖中提取標籤和句柄。你可以猜測,小區有這樣的信息,但沒有實際擔保,所以這意味着依靠無證行爲。事實證明,非對角線的小插曲有它(但對角線的小插曲沒有,所以如果你只是看着第一個小區你會被誤導),你可以做handles, labels = fig.get_axes()[1].get_legend_handles_labels()。但正如我所說,即使您僅使用記錄的API,這也是無證的行爲。

您也可以創建自己的手柄,但這會很麻煩,這就是爲什麼我查找快捷方式,即使沒有記錄。

+0

謝謝!這就是問題的答案。你有沒有在seaborn文檔中找到這個? –

+1

@WR我編輯了答案,如果我沒有解決您的疑慮,請告訴我。 – Goyo

+0

完成。好帖子!在這個問題上我沒有進一步的問題。非常感謝,@Goyo! –

3

這實際上比您想象的要容易得多。這只是實際matplot輸出中的默認設置。只需轉到輸出窗口頂部的配置子圖按鈕,稍微降低右邊界上限並將其修復。

Example with button to click circled

+0

哦,我看到你先創建一個Python圖形,然後設置圖例位置,然後將其保存爲圖像。所以你說,沒有辦法以編程方式設置它? –

+0

是的,我沒有找到。問題是matplot不會將其識別爲表格。我想你可以深入研究pairplot腳本,並在那裏看到有關它的修補程序,但我認爲它不是可編輯的,因爲你(和我)最初嘗試這樣做的方式。我在GitHub上看到了同樣的問題,也沒有人想到它。 – natelacombe