2017-10-12 174 views
3

我有一個圖例,其圖例固定在右上角:如何擴展圖例以適合圖表的高度?Matplotlib:垂直擴展圖例

borderaxespad=0.會水平擴展它,但我找不到垂直擴展的等效項。

我使用matplotlib 2.0

示例代碼:

import numpy as np 

x = np.linspace(0, 2*np.pi, 100) 
data = [np.sin(x * np.pi/float(el)) for el in range(1, 5)] 

fig, ax = plt.subplots(1) 
for key, el in enumerate(data): 
    ax.plot(x, el, label=str(key)) 
ax.legend(bbox_to_anchor=(1.04,1), loc="upper left", borderaxespad=0., mode='expand') 
plt.tight_layout(rect=[0,0,0.8,1]) 

主要生產:

enter image description here

回答

1

首先解釋從提問的輸出:當使用2元組表示法爲bbox_to_anchor,創建不程度的邊界框。 mode="expand"會將圖例水平擴展到該邊界框,該邊界框具有零延伸,有效地將其縮小到零大小。

問題是mode="expand"只會水平擴展圖例。 從the documentation

mode:{「擴大」,無}
如果模式被設置爲「擴展」的說明將是水平膨脹以填充所述軸區域(或bbox_to_anchor如果定義了傳說的大小)。

對於需要深入挖掘圖例內部的解決方案。首先,您需要使用4元組來設置bbox-to-anchor,並指定bbox的寬度和高度,bbox_to_anchor=(x0,y0,width,height),其中所有數字都在規範化的座標軸中。然後你需要計算圖例的_legend_box的高度。由於設置了一些填充,因此您需要從邊界框的高度中減去填充。爲了計算填充,必須知道當前圖例的字體大小。所有這些都必須在軸的位置最後更改後進行。

import matplotlib.pyplot as plt 
import numpy as np 

x = np.linspace(0, 2*np.pi, 100) 
data = [np.sin(x * np.pi/float(el)) for el in range(1, 5)] 

fig, ax = plt.subplots(1) 
for key, el in enumerate(data): 
    ax.plot(x, el, label=str(key)) 

# legend:  
leg = ax.legend(bbox_to_anchor=(1.04,0.0,0.2,1), loc="lower left", 
       borderaxespad=0, mode='expand') 

plt.tight_layout(rect=[0,0,0.8,1]) 

# do this after calling tight layout or changing axes positions in any way: 
fontsize = fig.canvas.get_renderer().points_to_pixels(leg._fontsize) 
pad = 2 * (leg.borderaxespad + leg.borderpad) * fontsize 
leg._legend_box.set_height(leg.get_bbox_to_anchor().height-pad) 

plt.show() 

enter image description here

+0

謝謝,這是一個偉大的答案。 你認爲這是值得把這個功能請求標記爲matplotlib嗎?我沒有看到水平/垂直傳奇之間不對稱的原因。 另外,如何將標籤間距的@jrjc建議整合到圖例中以均勻分佈標籤? – FLab

+0

我想可以加入這個matplotlib,使用像'mode =「expandboth」'等新標誌。問題將是結果應該是什麼樣子。如上所述,留下很多空白空間?或者垂直分配手柄,從而覆蓋設置的標籤間距?目前,我對創建圖例後如何設置標籤間距沒有任何想法。我可能會在某個時候考慮這個問題,但不是我想的那麼快。 – ImportanceOfBeingErnest

1

labelspacing可能是你找什麼呢?

fig, ax = plt.subplots(1) 
for key, el in enumerate(data): 
    ax.plot(x, el, label=str(key)) 
ax.legend(labelspacing=8, loc=6, bbox_to_anchor=(1, 0.5)) 
plt.tight_layout(rect=[0, 0, 0.9, 1]) 

它不是自動的,但你可能會發現一些關係figsize(這也是8這裏)。

loc=6, bbox_to_anchor=(1, 0.5)將以你的圖例右側爲中心。

其中給出: expand legend matplotib