
??Matplotlib是Python中最常用的可視化工具,可以非常方便的生成出版質(zhì)量級(jí)的圖片,只需幾行代碼,就可以生成直方圖、功率譜、條形圖、錯(cuò)誤圖、散點(diǎn)圖、餅圖以及基本的3D圖表。在使用中一般使用如下載入matplotlib的繪圖庫(kù):
import matplotlib.pyplot as plt
??下面我們一步一步來(lái)介紹使用matplotlib進(jìn)行繪圖的過(guò)程:
- 創(chuàng)建繪圖對(duì)象
figure(num = None,figsize = None,dpi = None, facecolor = None,edgecolor = None)
| 參數(shù) | 用法說(shuō)明 |
|---|---|
| num | 默認(rèn)為None,如果參數(shù)未提供,將創(chuàng)建新圖形,并且圖形編號(hào)將遞增。圖形對(duì)象將此數(shù)字保存在number 屬性中。如果提供了num,并且已存在具有此id的數(shù)字,請(qǐng)將其設(shè)置為活動(dòng)狀態(tài),并返回對(duì)它的引用。如果此圖不存在,則創(chuàng)建它并返回它。如果num是一個(gè)字符串,則窗口標(biāo)題將設(shè)置為此圖 num。 |
| figsize | 整數(shù)元組,指定圖形對(duì)象的寬度和高度,如未提供,默認(rèn)為figure.figsize。 |
| dpi | Dots Per Inch,每英寸點(diǎn)數(shù),指每一英寸長(zhǎng)度中,取樣、可顯示或輸出點(diǎn)的數(shù)目。 DPI是打印機(jī)、鼠標(biāo)等設(shè)備分辨率的度量單位。,如未提供,默認(rèn)為figure.dpi |
| facecolor | 設(shè)置圖形對(duì)象的背景顏色,如未提供,默認(rèn)為figure.facecolor。 |
| edgecolor | 設(shè)置圖形對(duì)象的邊框顏色,如未提供,默認(rèn)為figure.edgecolor。 |
更多參數(shù)請(qǐng)參考: matplotlib.pyplot.figure
- 繪制條形圖
matplotlib.pyplot.bar(left, height, alpha, width, facecolor, edgecolor, label, lw)
繪制水平條形圖時(shí)使用barh()參數(shù)用法相同
| 參數(shù) | 用法說(shuō)明 |
|---|---|
| left | 橫坐標(biāo)的位置序列 |
| height | 縱坐標(biāo)的數(shù)值序列,也就是柱形圖的高度 |
| alpha | 圖形透明度 |
| width | 柱形圖的寬度,一般設(shè)為0.8 |
| facecolor | 柱形圖的填充顏色 |
| edgecolor | 圖形邊緣的顏色 |
| label | 圖例 |
| lw | 邊緣線的寬度 |
我們通過(guò)幾個(gè)例子來(lái)熟悉這些參數(shù):
- 例1
import matplotlib.pyplot as plt
#城市
city = ['beijing','shanghai','chengdou','chongqing']
#gpd
gdp = [29876,32212,15015,21385]
plt.figure('City GDP',figsize=(8,4),dpi = 80)
#繪制柱形圖
plt.bar(city,gdp,alpha = 1,width = 0.4,label = 'GDP')
plt.xlabel('City')
plt.ylabel('GDP')
plt.title('City-GDP')
#顯示圖例
plt.legend()
#顯示圖形
plt.show()

- 例2
import matplotlib.pyplot as plt
import matplotlib
label_list = ['2014', '2015', '2016', '2017']
num_list1 = [20, 30, 15, 35]
num_list2 = [15, 30, 40, 20]
x = range(len(num_list1))
rects1 = plt.bar(left=x, height=num_list1, width=0.4, alpha=1, color='red', label="department-one")
rects2 = plt.bar(left=[i + 0.4 for i in x], height=num_list2, width=0.4, color='green', label="department-two")
#指定y軸的范圍
plt.ylim(0, 50)
plt.ylabel("quetity")
#設(shè)置坐標(biāo)點(diǎn)刻度顯示的值
plt.xticks([index + 0.2 for index in x], label_list)
plt.xlabel("year")
plt.title("company")
plt.legend()
#在相應(yīng)的條形圖上顯示當(dāng)前的數(shù)值
for rect in rects1:
#獲得條形圖的高度即數(shù)值
height = rect.get_height()
plt.text(rect.get_x() + rect.get_width() / 2, height+1, str(height), ha="center", va="bottom")
for rect in rects2:
height = rect.get_height()
plt.text(rect.get_x() + rect.get_width() / 2, height+1, str(height), ha="center", va="bottom")
#將圖片輸出到指定目錄
plt.savefig('/Users/wcjb/Documents/Machine Learning/Hist-1',dpi = 800)
plt.show()

- 例3
import matplotlib.pyplot as plt
import matplotlib
matplotlib.rcParams['font.sans-serif'] = ['SimHei']
matplotlib.rcParams['axes.unicode_minus'] = False
price = [39.5, 39.9, 45.4, 38.9, 33.34]
plt.barh(range(5), price, height=0.7, color='steelblue', alpha=0.8)
plt.yticks(range(5), ['one', 'two', 'three', 'four', 'five'])
#指定橫坐標(biāo)的范圍
plt.xlim(30,47)
plt.xlabel("price")
plt.title("book-price")
#enumerate() 函數(shù)用于將一個(gè)可遍歷的數(shù)據(jù)對(duì)象(如列表、元組或字符串)組合為一個(gè)索引序列,同時(shí)列出數(shù)據(jù)和數(shù)據(jù)下標(biāo).
for x, y in enumerate(price):
plt.text(y + 0.2, x - 0.1, '%s' % y)
plt.savefig('/Users/wcjb/Documents/Machine Learning/Hist-2',dpi = 800)
plt.show()

- 例4
import matplotlib.pyplot as plt
import matplotlib
label_list = ['2014', '2015', '2016', '2017']
num_list1 = [20, 30, 15, 35]
num_list2 = [15, 30, 40, 20]
x = range(len(num_list1))
rects1 = plt.bar(left=x, height=num_list1, width=0.45, alpha=0.8, color='red', label="one")
rects2 = plt.bar(left=x, height=num_list2, width=0.45, color='green', label="two", bottom=num_list1)
plt.ylim(0, 80)
plt.ylabel('quantity')
plt.xticks(x, label_list)
plt.xlabel("year")
plt.title("company")
plt.legend()
plt.savefig('/Users/wcjb/Documents/Machine Learning/Hist-3',dpi = 800)
plt.show()

在matplotlib可視化中如果需要顯示圖例,要使用legend();要顯示圖形則需使用show()。
- 繪制直方圖
??條形圖可以讓我們很直觀看到數(shù)據(jù)的大小,然而當(dāng)我們需要去關(guān)注數(shù)據(jù)的分布情況時(shí),直方圖可能是一個(gè)更好的選擇。直方圖描述的是一組數(shù)據(jù)的頻次分布,例如把年齡分成“0-5,5-10,……,80-85”17個(gè)組,統(tǒng)計(jì)一下中國(guó)人口年齡的分布情況,這樣為我們就可以很直觀的看到各個(gè)年齡段人數(shù)分布的情況。
matplotlib.pyplot.hist(data, bins, normed, facecolor, edgecolor, alpha)
| 參數(shù) | 用法說(shuō)明 |
|---|---|
| data | 必選參數(shù),繪圖數(shù)據(jù) |
| bins | 直方圖的長(zhǎng)條形數(shù)目,可選項(xiàng),默認(rèn)為10 |
| normed | 是否將得到的直方圖向量歸一化,可選項(xiàng),默認(rèn)為0,代表不歸一化,顯示頻數(shù)。normed=1,表示歸一化,顯示頻率。 |
import numpy as np
import matplotlib.pyplot as plt
# 生成1000個(gè)服從標(biāo)準(zhǔn)正態(tài)分布的隨機(jī)數(shù)據(jù)
data = np.random.randn(1000)
plt.figure(1,figsize =(8,4),dpi = 80)
plt.hist(data,bins = 50,normed = 1,alpha = 1,edgecolor = 'black')
plt.xlabel('intervak')
plt.ylabel('rate')
plt.title('Histogram')
plt.legend()
#將圖片保存在指定目錄
plt.savefig('/Users/wcjb/Documents/Machine Learning/Histgram',dpi = 800)
plt.show()

- 繪制餅圖
pie(size, explode, colors, labels, labeldistance, autopct, shadow=False, startangle, pctdistance)
| 參數(shù) | 用法說(shuō)明 |
|---|---|
| explode | 設(shè)置各部分突出 |
| label | 設(shè)置各部分標(biāo)簽 |
| labeldistance | 設(shè)置標(biāo)簽文本距圓心位置,1.1表示1.1倍半徑 |
| autopct | 設(shè)置圓里面文本 |
| shadow | 設(shè)置是否有陰影 |
| startangle | 起始角度,默認(rèn)從0開始逆時(shí)針轉(zhuǎn) |
| pctdistance | 設(shè)置圓內(nèi)文本距圓心距離 |
import matplotlib.pyplot as plt
import matplotlib
matplotlib.rcParams['font.sans-serif'] = ['SimHei']
matplotlib.rcParams['axes.unicode_minus'] = False
# 各部分標(biāo)簽
label_list = ["one", "two", "three"]
# 各部分比例大小
size = [55, 35, 10]
# 各部分顏色
color = ["red", "green", "blue"]
# 突出部分
explode = [0.05, 0, 0]
plt.pie(size, explode=explode, colors=color, labels=label_list, labeldistance=1.1, autopct="%1.1f%%", shadow=False, startangle=90, pctdistance=0.6)
# 設(shè)置橫軸和縱軸大小相等,這樣餅才是圓的,默認(rèn)輸出橢圓
plt.axis("equal")
plt.legend()
plt.savefig('/Users/wcjb/Documents/Machine Learning/pie',dpi = 800)
plt.show()
pie

- 繪制對(duì)數(shù)坐標(biāo)圖
??在matplotlib中有3個(gè)函數(shù)可以繪制對(duì)數(shù)坐標(biāo)圖,分別是:semilogx(),semilogy(),loglog(),它們分別表示對(duì)X軸,Y軸,XY軸取對(duì)數(shù)。
import numpy as np
import matplotlib.pyplot as plt
w=np.linspace(0.1,1000,1000)
p=np.abs(1/(1+0.1j*w))
plt.subplot(221)
plt.plot(w,p,lw=2)
plt.xlabel('X')
plt.ylabel('y')
plt.subplot(222)
plt.semilogx(w,p,lw=2)
plt.ylim(0,1.5)
plt.xlabel('log(X)')
plt.ylabel('y')
plt.subplot(223)
plt.semilogy(w,p,lw=2)
plt.ylim(0,1.5)
plt.xlabel('x')
plt.xlabel('log(y)')
plt.subplot(224)
plt.loglog(w,p,lw=2)
plt.ylim(0,1.5)
plt.savefig('/Users/wcjb/Documents/Machine Learning/log',dpi = 800)
plt.show()

subplot(i,j,k):在繪圖對(duì)象中創(chuàng)建子圖,相當(dāng)于將畫布分為
個(gè)子圖,在從左往右,從上到下的第k個(gè)子圖上繪制當(dāng)前圖形。
- 繪制極坐標(biāo)圖
??極坐標(biāo)系中的點(diǎn)由一個(gè)夾角和一段相對(duì)于中心位置的距離來(lái)表示。要繪制極坐標(biāo)圖只需將plot()函數(shù)中的polar屬性設(shè)為True便可。
import numpy as np
import matplotlib.pyplot as plt
theta=np.arange(0,2*np.pi,0.02)
plt.subplot(121,polar=True)
plt.plot(theta,2*np.ones_like(theta),lw=2)
plt.plot(theta,theta/6,'--',lw=2)
plt.subplot(122,polar=True)
plt.plot(theta,np.cos(5*theta),'--',lw=2)
plt.plot(theta,2*np.cos(4*theta),lw=2)
# 表示繪制半徑為0.5 1.0 1.5的三個(gè)同心圓,同時(shí)將這些半徑的值標(biāo)記在45度位置的那個(gè)直徑上面。
plt.rgrids(np.arange(0.5,2,0.5),angle=45)
# 表示在theta為0,45,90度的位置上標(biāo)記上度數(shù)。
plt.thetagrids([0,45,90])
plt.savefig('/Users/wcjb/Documents/Machine Learning/1',dpi = 800)
plt.show()
極坐標(biāo)

- 繪制散點(diǎn)圖
scatter(x, y, s=None, c=None, marker=None, cmap=None, norm=None, vmin=None, vmax=None, alpha=None, linewidths=None, verts=None, edgecolors=None, hold=None, data=None, **kwargs)
| 參數(shù) | 用法說(shuō)明 |
|---|---|
| x | 橫坐標(biāo)取值 |
| y | 縱坐標(biāo)取值 |
| s | 點(diǎn)的大小 |
| c | 設(shè)置點(diǎn)的顏色,可以是一個(gè)二維數(shù)組,其中的行是RGB或RGBA |
| maker | 指定繪圖點(diǎn)的形狀,0表示多邊形,1表示是星型,2表示放射型,3表示圓形 |
| alpha | 表示透明度 |
import matplotlib.pyplot as plt
import numpy as np
x = np.random.rand(1000)
y = np.random.rand(1000)
size = np.random.rand(1000) * 50
color = np.random.rand(1000)
plt.scatter(x, y, size, color)
#顯示顏色漸變條
plt.colorbar()
plt.savefig('/Users/wcjb/Documents/Machine Learning/sample',dpi = 400)
plt.show()
散點(diǎn)圖

- 繪制等高線
??在機(jī)器學(xué)習(xí)中,有時(shí)會(huì)需要繪制梯度下降算法的圖形,可使用等高線的方法來(lái)實(shí)現(xiàn)contour(x,y,f(x,y)):繪制等高線圖,不進(jìn)行填充
contourf(x,y,f(x,y),cmap=plt.cm.hot) :繪制等高線圖并進(jìn)行填充
import numpy as np
import matplotlib.pyplot as plt
def f(x, y):
return x**2+y**2+x*y
n = 256
x = np.linspace(-3, 3, n)
y = np.linspace(-3, 3, n)
X, Y = np.meshgrid(x, y)
#繪制等高線并進(jìn)行填充
plt.contourf(X, Y, f(X, Y), 8, alpha=.75, cmap='jet')
#繪制等高線,不進(jìn)行填充
C = plt.contour(X, Y, f(X, Y), 8, colors='black', linewidth=0.5)
#顯示等高線
plt.clabel(C, inline=True, fontsize=12)
plt.show()

- 繪制曲線
plot(x,y,label,color,linewidth)
| 參數(shù) | 用法說(shuō)明 |
|---|---|
| x,y | 相應(yīng)的橫縱坐標(biāo)數(shù)據(jù) |
| label | 圖例 |
| color | 線的顏色 |
| linewidth | 指定線的寬度 |
import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(-10,10,200)
y = np.sin(x**2+2)
plt.plot(x,y,label='$sin(2x^2+2)$',color = 'blue',linewidth = 3)
plt.xlabel('x')
plt.ylabel('y')
plt.legend()
plt.savefig('/Users/wcjb/Documents/Machine Learning/sample',dpi = 400)
plt.show()

- 常用函數(shù)補(bǔ)充
| 函數(shù) | 用法 |
|---|---|
| grid() | 參數(shù)為True時(shí),在圖形中顯示網(wǎng)格線 |
| text(x, y, s[, fontsize, color]) | 在坐標(biāo)(x,y)顯示文本s ,fontsize指定字體大小 |
| annotate() | 對(duì)圖片上某個(gè)點(diǎn)進(jìn)行注釋 |
| xticks()/yticks() | 設(shè)置x,y軸的刻度標(biāo)簽值 |
| spines() | 移動(dòng)坐標(biāo)軸 |
| axis([x1,x2,y1,y2]) | 同時(shí)設(shè)置x軸和y軸的范圍 |
| gca() | 返回當(dāng)前axes(matplotlib.axes.Axes) |
| gcf() | 返回當(dāng)前figure(matplotlib.figure.Figure) |
| clf() | 清理當(dāng)前figure |
| cla() | 清理當(dāng)前axes |
| close() | 一副figure直到顯式的調(diào)用close()時(shí)才會(huì)釋放她所占用的資源; |
防止繪制大量圖片時(shí)內(nèi)存占用過(guò)高
- 一些有趣的實(shí)例
import numpy as np
import matplotlib.pyplot as plt
n = 8
#生成二維數(shù)組
X, Y = np.mgrid[-n:n, -n:n]
color = np.random.rand(2*n)+3
#繪制一個(gè)二維方向場(chǎng)域
plt.quiver(Y,X,color)
plt.title('A 2-D field of arrows')
plt.colorbar()
plt.savefig('/Users/wcjb/Documents/Machine Learning/arrows')
plt.show()

np.mgrid[start:end:step]:生成二維數(shù)組,start:開始坐標(biāo),stop:結(jié)束坐標(biāo)(不包括,step:步長(zhǎng),默認(rèn)為1。
import numpy as np
X,Y=np.mgrid[-4:4,-3:3]
print(X,'\n\n',Y)

quiver(U,V,X,Y,C):U和V是箭頭數(shù)據(jù),X和Y設(shè)置箭頭的位置,C設(shè)置箭頭的顏色。這些參數(shù)可以是1-D或2-D陣列或序列。
# 根據(jù)實(shí)時(shí)數(shù)據(jù)進(jìn)行圖形動(dòng)態(tài)更新
from time import sleep
from threading import Thread
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.widgets import Button
#同時(shí)創(chuàng)建子圖和子圖網(wǎng)格,即同時(shí)建立一個(gè)fig對(duì)象和axis對(duì)象,subplot()只能創(chuàng)建子圖網(wǎng)格
fig,ax = plt.subplots()
#設(shè)置圖形的顯示位置
plt.subplots_adjust(bottom = 0.2)
#實(shí)驗(yàn)數(shù)據(jù)
range_start,range_end,range_step = 0,1,0.005
t = np.arange(range_start,range_end,range_step)
s = np.sin(4*np.pi*t)
l,= plt.plot(t,s,lw = 2)
#自定義類,用于封裝兩個(gè)按鈕的單擊事件處理函數(shù)
class ButtonHandler:
def __init__(self):
self.flag = True
self.range_s,self.range_e,self.range_step = 0,1,0.005
#線程函數(shù),用于更新數(shù)據(jù)并重新繪制圖形
def threadStart(self):
while self.flag:
sleep(0.02)
self.range_s += self.range_step
self.range_e += self.range_step
t = np.arange(self.range_s,self.range_e,self.range_step)
ydata = np.sin(4*np.pi*t)
# 更新數(shù)據(jù)
l.set_xdata(t-t[0])
l.set_ydata(ydata)
# 重新繪制圖形
plt.draw()
def Start(self,event):
self.flag = True
# 創(chuàng)建并啟動(dòng)新進(jìn)程
t = Thread(target = self.threadStart)
t.start()
def Stop(self,event):
self.flag = False
callback = ButtonHandler()
# 創(chuàng)建按鈕并設(shè)置單擊事件處理函數(shù)
axprev = plt.axes([0.81,0.05,0.1,0.075])
bprrev = Button(axprev,'Stop')
bprrev.on_clicked(callback.Stop)
axnext = plt.axes([0.7,0.05,0.1,0.075])
bnext = Button(axnext,'Start')
bnext.on_clicked(callback.Start)
plt.show()
