作者
王偉同學(xué)
已獲原作者授權(quán),如需轉(zhuǎn)載,請(qǐng)聯(lián)系原作者。
一篇快速上手 Matplotlib 的好文章~
在開始正式介紹 Matplotlib 用法之前,先來簡(jiǎn)單了解下 Matplotlib。
Matplotlib 是 Python 的一個(gè)繪圖庫(kù)。它包含了大量的工具,你可以使用這些工具創(chuàng)建各種圖形,包括簡(jiǎn)單的散點(diǎn)圖,正弦曲線,甚至是三維圖形。
目錄
1. 畫一個(gè)簡(jiǎn)單的圖形
2. 在一張圖紙里繪制多個(gè)圖形
3. 更多設(shè)置
3.1 設(shè)置 figure
3.2 設(shè)置標(biāo)題
3.3 設(shè)置坐標(biāo)軸
3.4 設(shè)置 label 和 legend
3.5 添加注釋
4. 使用子圖
5. 常見的圖形
5.1 散點(diǎn)圖
5.2 柱狀圖
6. 中文亂碼解決
# 導(dǎo)入相關(guān)模塊
import matplotlib.pyplot as plt
import numpy as np
畫一個(gè)簡(jiǎn)單的圖形
這里我們通過畫出一個(gè)正弦曲線圖來講解下基本用法。
首先通過 np.linspace 方式生成 x,它包含了 50 個(gè)元素的數(shù)組,這 50 個(gè)元素均勻的分布在 [0, 2pi] 的區(qū)間上。然后通過 np.sin(x) 生成 y。
x = np.linspace(0, 2 * np.pi, 50)
y = np.sin(x)
有了 x 和 y 數(shù)據(jù)之后,我們通過 plt.plot(x, y) 來畫出圖形,并通過 plt.show() 來顯示。
plt.plot(x, y)
plt.show()
在一張圖紙里繪制多個(gè)圖形
有時(shí)候,可能需要在一個(gè)圖紙里繪制多個(gè)圖形,這里我們同時(shí)繪制了 (x, y), (x, y * 2)兩個(gè)圖形。
plt.plot(x, y)
plt.plot(x, y * 2)
plt.show()
繪制出圖形之后,我們可以自己調(diào)整更多的樣式,比如顏色、點(diǎn)、線。
plt.plot(x, y, 'y*-')
plt.plot(x, y * 2, 'm--')
plt.show()
可以看到,設(shè)置樣式時(shí),就是增加了一個(gè)字符串參數(shù),比如 'y*-' ,其中 y 表示黃色,* 表示 星標(biāo)的點(diǎn),- 表示實(shí)線。
這里列舉一些常見的顏色表示方式:
顏色表示方式
藍(lán)色b
綠色g
紅色r
青色c
品紅m
黃色y
黑色k
白色w
常見的點(diǎn)的表示方式:
點(diǎn)的類型表示方式
點(diǎn).
像素,
圓o
方形s
三角形^
常見的線的表示方式:
線的類型表示方式
直線-
虛線--
點(diǎn)線:
點(diǎn)劃線-.
更多設(shè)置
Matplotlib 支持各種靈活的設(shè)置,這里我們列舉一些常見的內(nèi)容。
設(shè)置 figure
你可以認(rèn)為Matplotlib繪制的圖形都在一個(gè)默認(rèn)的 figure 中,當(dāng)然了,你可以自己創(chuàng)建 figure,好處就是可以控制更多的參數(shù),常見的就是控制圖形的大小,這里創(chuàng)建一個(gè) figure,設(shè)置大小為 (6, 3)。
plt.figure(figsize=(6, 3))
plt.plot(x, y)
plt.plot(x, y * 2)
plt.show()
設(shè)置標(biāo)題
來看下如何設(shè)置標(biāo)題。
plt.plot(x, y)
plt.plot(x, y * 2)
plt.title('sin(x) & 2sin(x)')
plt.show()
直接通過 plt.title 即可設(shè)置圖形標(biāo)題。
設(shè)置坐標(biāo)軸
來看下如何設(shè)置坐標(biāo)軸的范圍以及名稱。
plt.plot(x, y)
plt.plot(x, y * 2)
plt.xlim((0, np.pi + 1))
plt.ylim((-3, 3))
plt.xlabel('X')
plt.ylabel('Y')
plt.show()
通過 xlim 和 ylim 來設(shè)限定軸的范圍,通過 xlabel 和 ylabel 來設(shè)置軸的名稱。
此外,我們也可以通過 xticks 和 yticks 來設(shè)置軸的刻度。
plt.plot(x, y)
plt.plot(x, y * 2)
plt.xticks((0, np.pi * 0.5, np.pi, np.pi * 1.5, np.pi * 2))
plt.show()
設(shè)置 label 和 legend
設(shè)置 label 和 legend 的目的就是為了區(qū)分出每個(gè)數(shù)據(jù)對(duì)應(yīng)的圖形名稱。
plt.plot(x, y, label='sin(x)')
plt.plot(x, y * 2, label='2sin(x)')
# plt.legend()
plt.legend(loc='best')
plt.show()
添加注釋
有時(shí)候我們需要對(duì)特定的點(diǎn)進(jìn)行標(biāo)注,我們可以使用 plt.annotate 函數(shù)來實(shí)現(xiàn)。
這里我們要標(biāo)注的點(diǎn)是 (x0, y0) = (π, 0)。
我們也可以使用 plt.text 函數(shù)來添加注釋。
plt.plot(x, y)
x0 = np.pi
y0 = 0
# 畫出標(biāo)注點(diǎn)
plt.scatter(x0, y0, s=50)
plt.annotate('sin(np.pi)=%s' % y0, xy=(np.pi, 0), xycoords='data', xytext=(+30, -30),
textcoords='offset points', fontsize=16,
arrowprops=dict(arrowstyle='->', connectionstyle='arc3,rad=.2'))
plt.text(0.5, -0.25, 'sin(np.pi) = 0', fontdict={'size': 16, 'color': 'r'})
plt.show()
對(duì)于 annotate 函數(shù)的參數(shù),做一個(gè)簡(jiǎn)單解釋:
'sin(np.pi)=%s' % y0 代表標(biāo)注的內(nèi)容,可以通過字符串 %s 將 y0 的值傳入字符串;
參數(shù) xycoords='data' 是說基于數(shù)據(jù)的值來選位置;
xytext=(+30, -30) 和 textcoords='offset points' 表示對(duì)于標(biāo)注位置的描述 和 xy 偏差值,即標(biāo)注位置是 xy 位置向右移動(dòng) 30,向下移動(dòng)30;
arrowprops 是對(duì)圖中箭頭類型和箭頭弧度的設(shè)置,需要用 dict 形式傳入。
使用子圖
有時(shí)候我們需要將多張子圖展示在一起,可以使用 subplot() 實(shí)現(xiàn)。即在調(diào)用 plot() 函數(shù)之前需要先調(diào)用 subplot() 函數(shù)。該函數(shù)的第一個(gè)參數(shù)代表子圖的總行數(shù),第二個(gè)參數(shù)代表子圖的總列數(shù),第三個(gè)參數(shù)代表活躍區(qū)域。
ax1 = plt.subplot(2, 2, 1) # (行,列,活躍區(qū))
plt.plot(x, np.sin(x), 'r')
ax2 = plt.subplot(2, 2, 2, sharey=ax1) # 與 ax1 共享y軸
plt.plot(x, 2 * np.sin(x), 'g')
ax3 = plt.subplot(2, 2, 3)
plt.plot(x, np.cos(x), 'b')
ax4 = plt.subplot(2, 2, 4, sharey=ax3) # 與 ax3 共享y軸
plt.plot(x, 2 * np.cos(x), 'y')
plt.show()
上面的 subplot(2, 2, x) 表示將圖像窗口分為 2 行 2 列。x 表示當(dāng)前子圖所在的活躍區(qū)。
可以看到,上面的每個(gè)子圖的大小都是一樣的。有時(shí)候我們需要不同大小的子圖。比如將上面第一張子圖完全放置在第一行,其他的子圖都放在第二行。
ax1 = plt.subplot(2, 1, 1) # (行,列,活躍區(qū))
plt.plot(x, np.sin(x), 'r')
ax2 = plt.subplot(2, 3, 4)
plt.plot(x, 2 * np.sin(x), 'g')
ax3 = plt.subplot(2, 3, 5, sharey=ax2)
plt.plot(x, np.cos(x), 'b')
ax4 = plt.subplot(2, 3, 6, sharey=ax2)
plt.plot(x, 2 * np.cos(x), 'y')
plt.show()
簡(jiǎn)單解釋下,plt.subplot(2, 1, 1) 將圖像窗口分為了 2 行 1 列, 當(dāng)前活躍區(qū)為 1。
使用 plt.subplot(2, 3, 4) 將整個(gè)圖像窗口分為 2 行 3 列, 當(dāng)前活躍區(qū)為 4。
解釋下為什么活躍區(qū)為 4,因?yàn)樯弦徊街惺褂?nbsp;plt.subplot(2, 1, 1) 將整個(gè)圖像窗口分為 2 行 1 列, 第1個(gè)小圖占用了第1個(gè)位置, 也就是整個(gè)第1行. 這一步中使用 plt.subplot(2, 3, 4) 將整個(gè)圖像窗口分為 2 行 3 列, 于是整個(gè)圖像窗口的第1行就變成了3列, 也就是成了3個(gè)位置, 于是第2行的第1個(gè)位置是整個(gè)圖像窗口的第4個(gè)位置。
常見的圖形
這里帶大家畫一些常見的示例圖。
散點(diǎn)圖
首先來看下如何繪制散點(diǎn)圖。
k = 500
x = np.random.rand(k)
y = np.random.rand(k)
size = np.random.rand(k) * 50 # 生成每個(gè)點(diǎn)的大小
colour = np.arctan2(x, y) # 生成每個(gè)點(diǎn)的顏色大小
plt.scatter(x, y, s=size, c=colour)
plt.colorbar() # 添加顏色欄
plt.show()
上面我們首先生成了要繪制的數(shù)據(jù)的點(diǎn)x 和 y,接下來為每個(gè)數(shù)據(jù)點(diǎn)生成控制大小的數(shù)組 size,然后未每個(gè)數(shù)據(jù)點(diǎn)生成控制顏色的數(shù)組 colour。最后通過 colorbar() 來增加一個(gè)顏色欄。
柱狀圖
柱狀圖我們經(jīng)常會(huì)用到,我們來看下如何畫出柱狀圖,并在圖上標(biāo)注出數(shù)據(jù)對(duì)應(yīng)的數(shù)值。
k = 10
x = np.arange(k)
y = np.random.rand(k)
plt.bar(x, y) # 畫出 x 和 y 的柱狀圖
# 增加數(shù)值
for x, y in zip(x, y):
plt.text(x, y , '%.2f' % y, ha='center', va='bottom')
plt.show()
生成數(shù)據(jù) x 和 y 之后,調(diào)用 plt.bar 函數(shù)繪制出柱狀圖,然后通過 plt.text 標(biāo)注數(shù)值,設(shè)置參數(shù) ha='center' 橫向居中對(duì)齊,設(shè)置 va='bottom'縱向底部(頂部)對(duì)齊。
中文亂碼解決
Matplotlib 有個(gè)讓人惱火的問題是,默認(rèn)情況下,Matplotlib 中文會(huì)亂碼。
x = ['北京', '上海', '深圳', '廣州']
y = [60000, 58000, 50000, 52000]
plt.plot(x, y)
plt.show()
可以看到,上面所有的中文都亂碼了,顯示成方框了,如何解決呢?
其實(shí)只需要配置下后臺(tái)字體即可。
plt.rcParams['font.sans-serif']=['SimHei'] #用來正常顯示中文標(biāo)簽
plt.rcParams['axes.unicode_minus']=False #用來正常顯示負(fù)號(hào)
plt.plot(x, y)
plt.show()