Matplotlib基础--自定义图标图例
圖例可以為可視化賦予實際含義,為不同的圖標元素附上明確說明。我們前面看到了一些簡單的圖例創(chuàng)建例子;本小節(jié)中我們來介紹一下在 Matplotlib 中自定義圖例的位置和進行美化的方法。
可以使用plt.legend()函數(shù)來創(chuàng)建最簡單的圖例,這個函數(shù)能自動創(chuàng)建任何帶有標簽屬性的圖表元素的圖例:
import matplotlib.pyplot as plt
plt.style.use('classic')
import numpy as np
x = np.linspace(0, 10, 1000)
fig, ax = plt.subplots()
ax.plot(x, np.sin(x), '-b', label='Sine')
ax.plot(x, np.cos(x), '--r', label='Cosine')
ax.axis('equal')
leg = ax.legend();
plt.show()
但除此之外還有很多能自定義圖例的方法。例如,我們可以指定圖例位置并且去除邊框:
ax.legend(loc='upper left', frameon=False) fig
我們可以使用ncol屬性設置圖例中每行的列數(shù):
ax.legend(frameon=False, loc='lower center', ncol=2) fig
還可以使用圓角方框(fancybox)或者增加陰影,設置方框的透明度(alpha 值)或修改文字的邊距:
ax.legend(fancybox=True, framealpha=1, shadow=True, borderpad=1) fig
要獲取更多 legend 函數(shù)的可用選項信息,請參考plt.legend的文檔字符串。
選擇設置圖例的元素
正如我們前面例子所示,繪制的圖例默認包括所有帶標簽的元素。如果這不是想要的效果,我們可以調整哪些元素和標簽會出現(xiàn)在圖例當中,這可以通過設置 plot 函數(shù)或方法返回的對象實現(xiàn)。plt.plot函數(shù)能夠同時產生多條折線,然后將這些線條的實例列表返回。將其中的部分實例傳遞到plt.legend()函數(shù)就能設置哪些線條會出現(xiàn)在圖例中,再通過一個標簽的列表指定圖例的名稱:
y = np.sin(x[:, np.newaxis] + np.pi * np.arange(0, 2, 0.5)) lines = plt.plot(x, y) # lines是一個線條實例的列表 plt.legend(lines[:2], ['first', 'second']);
作者更加傾向于使用第一種方式,因為更加清晰。通過將標簽應用在圖表元素上,然后繪制到圖例中:
plt.plot(x, y[:, 0], label='first') plt.plot(x, y[:, 1], label='second') plt.plot(x, y[:, 2:]) plt.legend(framealpha=1, frameon=True);
請注意默認情況下,legend 會忽略所有不帶標簽的元素。
散點大小的圖例
某些情況下默認的圖例不足以滿足特定的可視化需求。例如,你在使用散點的大小來標記數(shù)據(jù)的某個特征,然后希望創(chuàng)建一個相應的圖例。下面的例子是加州城市人口的散點圖(你們可以用自己文件替換),我們使用散點的大小表現(xiàn)該城市的面積,散點的顏色來表現(xiàn)城市的人口數(shù)量(自然對數(shù)值)。我們希望使用一個圖例來指明散點尺寸的比例,同時用一個顏色條來說明人口數(shù)量,我們可以通過自定義繪制一些標簽數(shù)據(jù)來實現(xiàn)尺寸圖例:
譯者注:新版 Matplotlib 已經取消 aspect 參數(shù),此處改為使用新的'scaled'參數(shù)調用 axis 函數(shù)。
import pandas as pd
cities = pd.read_csv(r'D:pythonGithub學習材料Python數(shù)據(jù)科學手冊datacalifornia_cities.csv')
# 提取我們感興趣的數(shù)據(jù)
lat, lon = cities['latd'], cities['longd']
population, area = cities['population_total'], cities['area_total_km2']
# 繪制散點圖,使用尺寸代表面積,顏色代表人口,不帶標簽
plt.scatter(lon, lat, label=None,
c=np.log10(population), cmap='viridis',
s=area, linewidth=0, alpha=0.5)
plt.axis('scaled')
plt.xlabel('longitude')
plt.ylabel('latitude')
plt.colorbar(label='log$_{10}$(population)')
plt.clim(3, 7)
# 下面我們創(chuàng)建圖例:
# 使用空列表繪制圖例中的散點,使用不同面積和標簽,帶透明度
for area in [100, 300, 500]:
plt.scatter([], [], c='k', alpha=0.3, s=area,
label=str(area) + ' km$^2$')
plt.legend(scatterpoints=1, frameon=False, labelspacing=1, title='City Area')
plt.title('California Cities: Area and Population');
之前的圖例都關聯(lián)著圖表上的一些對象,因此如果我們需要展示圖例的話我們首先需要繪制圖表元素。在上例中,我們需要的圖例對象(灰色圓圈)不在圖表上,因此我們采用繪制空列表的方式將它們仿造在圖表上(實際上圖上沒有點),但是還是需要注意,只有那些帶標簽的元素才會出現(xiàn)在圖例中。
通過繪制空列表,我們創(chuàng)建了三個帶標簽的對象,然后就可以出現(xiàn)在圖例當中,這個圖例就能表示出有關城市面積的相關信息。這個策略在很多復雜可視化圖表構建過程中都被用到。
最后我們注意到這個圖表實際上是一個地理位置圖表,如果我們能在上面繪制州界線或其他地圖相關的元素的話,會更加清晰。Matplotlib 提供了一個 Basemap 額外工具集來實現(xiàn)這個目標。
多重圖例
有時候我們可能需要在同一個圖表維度中設計多個圖例。不幸的是,Matplotlib 并沒有提供很簡單的方式實現(xiàn):通過標準的legend接口,只能在整張圖表上創(chuàng)建一個圖例。如果你試圖使用plt.legend()或ax.legend()創(chuàng)建第二個圖例,那么第二條語句創(chuàng)建的圖例會覆蓋第一條語句創(chuàng)建的。我們只能通過從底層開始來創(chuàng)建一個新的圖例 artist 這種方法來解決這個問題,然后使用ax.add_artist()的底層方法手動將第二個作者加到圖表上:
fig, ax = plt.subplots()
lines = []
styles = ['-', '--', '-.', ':']
x = np.linspace(0, 10, 1000)
for i in range(4):
lines += ax.plot(x, np.sin(x - i * np.pi / 2),
styles[i], color='black')
ax.axis('equal')
# 指定第一個圖例的線條和標簽
ax.legend(lines[:2], ['line A', 'line B'],
loc='upper right', frameon=False)
# 手動創(chuàng)建第二個圖例,并將作者添加到圖表中
from matplotlib.legend import Legend
leg = Legend(ax, lines[2:], ['line C', 'line D'],
loc='lower right', frameon=False)
ax.add_artist(leg);
plt.show()
上例展示了用來組成任何 Matplotlib 圖表的底層 artist 對象的簡單說明。如果你去查看ax.legend()的源代碼(你可以通過 IPython 的ax.legend?幫助工具做到),你可以看到這個方法包含了用來構建合適Legend的 artist 對象的邏輯,構建的對象被保存在legend_屬性當中,當繪制時被添加到圖表上進行展示.
總結
以上是生活随笔為你收集整理的Matplotlib基础--自定义图标图例的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 无线 WIFI 的13个信道频率范围(转
- 下一篇: Ajax 简单介绍