Matplotlib基礎--自定義圖標圖例


圖例可以為可視化賦予實際含義,為不同的圖標元素附上明確說明。我們前面看到了一些簡單的圖例創建例子;本小節中我們來介紹一下在 Matplotlib 中自定義圖例的位置和進行美化的方法。

可以使用plt.legend()函數來創建最簡單的圖例,這個函數能自動創建任何帶有標簽屬性的圖表元素的圖例:

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屬性設置圖例中每行的列數:

ax.legend(frameon=False, loc='lower center', ncol=2)
fig

 還可以使用圓角方框(fancybox)或者增加陰影,設置方框的透明度(alpha 值)或修改文字的邊距:

ax.legend(fancybox=True, framealpha=1, shadow=True, borderpad=1)
fig

要獲取更多 legend 函數的可用選項信息,請參考plt.legend的文檔字符串。

選擇設置圖例的元素

正如我們前面例子所示,繪制的圖例默認包括所有帶標簽的元素。如果這不是想要的效果,我們可以調整哪些元素和標簽會出現在圖例當中,這可以通過設置 plot 函數或方法返回的對象實現plt.plot函數能夠同時產生多條折線,然后將這些線條的實例列表返回。將其中的部分實例傳遞到plt.legend()函數就能設置哪些線條會出現在圖例中,再通過一個標簽的列表指定圖例的名稱:

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 會忽略所有不帶標簽的元素。

散點大小的圖例

某些情況下默認的圖例不足以滿足特定的可視化需求。例如,你在使用散點的大小來標記數據的某個特征,然后希望創建一個相應的圖例。下面的例子是加州城市人口的散點圖(你們可以用自己文件替換),我們使用散點的大小表現該城市的面積,散點的顏色來表現城市的人口數量(自然對數值)。我們希望使用一個圖例來指明散點尺寸的比例,同時用一個顏色條來說明人口數量,我們可以通過自定義繪制一些標簽數據來實現尺寸圖例:

譯者注:新版 Matplotlib 已經取消 aspect 參數,此處改為使用新的'scaled'參數調用 axis 函數

import pandas as pd
cities = pd.read_csv(r'D:\python\Github學習材料\Python數據科學手冊\data\california_cities.csv')

# 提取我們感興趣的數據
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)

# 下面我們創建圖例:
# 使用空列表繪制圖例中的散點,使用不同面積和標簽,帶透明度
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');

之前的圖例都關聯着圖表上的一些對象,因此如果我們需要展示圖例的話我們首先需要繪制圖表元素。在上例中,我們需要的圖例對象(灰色圓圈)不在圖表上,因此我們采用繪制空列表的方式將它們仿造在圖表上(實際上圖上沒有點),但是還是需要注意,只有那些帶標簽的元素才會出現在圖例中。

通過繪制空列表,我們創建了三個帶標簽的對象,然后就可以出現在圖例當中,這個圖例就能表示出有關城市面積的相關信息。這個策略在很多復雜可視化圖表構建過程中都被用到。

最后我們注意到這個圖表實際上是一個地理位置圖表,如果我們能在上面繪制州界線或其他地圖相關的元素的話,會更加清晰。Matplotlib 提供了一個 Basemap 額外工具集來實現這個目標

多重圖例

有時候我們可能需要在同一個圖表維度中設計多個圖例。不幸的是,Matplotlib 並沒有提供很簡單的方式實現:通過標准的legend接口,只能在整張圖表上創建一個圖例。如果你試圖使用plt.legend()ax.legend()創建第二個圖例,那么第二條語句創建的圖例會覆蓋第一條語句創建的。我們只能通過從底層開始來創建一個新的圖例 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)

# 手動創建第二個圖例,並將作者添加到圖表中
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_屬性當中,當繪制時被添加到圖表上進行展示.


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM