我正在繪製相同類型的信息,但對於不同的國家,多個子圖與matplotlib。也就是說,我在一個3x3網格上有9個圖,所有線都有相同的值(當然,每行的值不同)。如何使用matplotlib爲許多subplots製作單個圖例?
但是,我還沒有想出如何將一個圖例(因爲所有9個子圖都有相同的行)放在一個圖上。
我該怎麼做?
我正在繪製相同類型的信息,但對於不同的國家,多個子圖與matplotlib。也就是說,我在一個3x3網格上有9個圖,所有線都有相同的值(當然,每行的值不同)。如何使用matplotlib爲許多subplots製作單個圖例?
但是,我還沒有想出如何將一個圖例(因爲所有9個子圖都有相同的行)放在一個圖上。
我該怎麼做?
figlegend可能是你在找什麼:http://matplotlib.org/api/pyplot_api.html#matplotlib.pyplot.figlegend
這裏舉例:http://matplotlib.org/examples/pylab_examples/figlegend_demo.html
又如:
plt.figlegend(lines, labels, loc = 'lower center', ncol=5, labelspacing=0.)
或:
fig.legend(lines, labels, loc = (0.5, 0), ncol=5)
你只需要在你的循環之外請求傳說一次。
例如,在這種情況下,我有4個子圖,具有相同的線條和一個圖例。
from matplotlib.pyplot import *
ficheiros = ['120318.nc', '120319.nc', '120320.nc', '120321.nc']
fig = figure()
fig.suptitle('concentration profile analysis')
for a in range(len(ficheiros)):
# dados is here defined
level = dados.variables['level'][:]
ax = fig.add_subplot(2,2,a+1)
xticks(range(8), ['0h','3h','6h','9h','12h','15h','18h','21h'])
ax.set_xlabel('time (hours)')
ax.set_ylabel('CONC ($\mu g. m^{-3}$)')
for index in range(len(level)):
conc = dados.variables['CONC'][4:12,index] * 1e9
ax.plot(conc,label=str(level[index])+'m')
dados.close()
ax.legend(bbox_to_anchor=(1.05, 0), loc='lower left', borderaxespad=0.)
# it will place the legend on the outer right-hand side of the last axes
show()
'figlegend',如Evert所要求的,似乎是一個更好的解決方案;) – carla 2012-03-23 11:06:13
'fig.legend()'的問題是它需要對所有線(圖)進行識別......對於每個子圖,我正在使用一個循環來生成這些行,唯一能解決這個問題的方案是在第二個循環之前創建一個空列表,然後在創建行時添加這些行......然後我使用這個列表作爲對'fig.legend()'函數的一個參數。 – carla 2012-03-23 12:06:30
類似的問題[這裏](https://stackoverflow.com/questions/22001756/one-legend-for-all-subplots-in-pyplot) – 2017-08-02 07:34:52
對於單個傳說在figure
自動定位與許多軸,就像subplots()
獲得的,下面的解決方案工作得很好:
plt.legend(lines, labels, loc = 'lower center', bbox_to_anchor = (0,-0.1,1,1),
bbox_transform = plt.gcf().transFigure)
隨着bbox_to_anchor
和bbox_transform=plt.gcf().transFigure
要定義將您的figure
大小的新邊界框作爲loc
的參考。使用(0,-0.1,1,1)
稍微向下移動此bouding框以防止圖例被放置在其他藝術家之上。
OBS:在您使用fig.set_size_inches()
並在您使用fig.tight_layout()
或者simpy'loc ='upper center',bbox_to_anchor =(0.5,0),bbox_transform = plt.gcf()。transFigure',它不會重疊。 – 2016-08-07 11:45:17
我仍然不確定爲什麼,但Evert的解決方案對我無效 - 這個傳說不斷被切斷。這個解決方案(和davor的評論一起)非常乾淨地工作 - 傳說被放置如預期並且完全可見。謝謝! – 2016-12-11 13:41:20
還有一個很好的功能get_legend_handles_labels()
您可以在最後一個軸打電話(如果你在它們之間迭代),將收集你所需要的一切使用此解決方案label=
自變量:
handles, labels = ax.get_legend_handles_labels()
fig.legend(handles, labels, loc='upper center')
這應該是最好的答案。 – naught101 2017-12-04 07:28:47
這個答案是對@埃弗特在傳說中的補充。
由於圖例和子圖的標題重疊,我第一次嘗試@ Evert的解決方案失敗。
實際上,重疊是由fig.tight_layout()
引起的,它會在不考慮圖形圖例的情況下更改子圖的佈局。但是,fig.tight_layout()
是必要的。
爲了避免重疊,我們可以告訴fig.tight_layout()
給圖形的圖例留出空間fig.tight_layout(rect=(0,0,1,0.9))
。
我知道我想要放在圖例中的幾行,但是如何獲得'lines'變量來放入'legend'的參數呢? – 2017-04-10 12:51:58
@patapouf_ai'lines'是從'axes.plot()'返回的結果列表(即每個'axes.plot'或類似的例程返回一個「行」)。另請參閱鏈接的示例。 – Evert 2017-04-10 20:13:46