在Python中使用Matplotlib繪制常見圖表方式
Matplotlib 是一個非常強大的 Python 畫圖工具,通過繪制線圖、散點圖、等高線圖、條形圖、柱狀圖、3D 圖形、甚至是圖形動畫等,可以更加直觀的呈現(xiàn)科學計算等遇到的大量數(shù)據(jù)。
1、基本元素
在matplotlib的層級結(jié)構(gòu)中,最高層是由matplotlib.pyplot模塊提供的“狀態(tài)機環(huán)境”(state-machine environment),通過它來為當前維度繪制圖像元素,例如曲線、文本、圖片等。接下來一層是第一級的面向?qū)ο蠼涌?,在這一層中用戶可以使用pyplot創(chuàng)建并追蹤圖像對象,并由此創(chuàng)建一個或多個數(shù)據(jù)軸系,這些軸系在之后用于圖的繪制。
如下所示為圖像的各個元素:
Figure指的是整張圖片對象,用于包含一個或多個數(shù)據(jù)軸系(Axes),如果沒Axes,則圖像為空。
fig = plt.figure() # 創(chuàng)建一個圖像對象 fig.suptitle('No axes on this figure') # 添加一個標題 fig, ax_lst = plt.subplots(2, 2) # 創(chuàng)建包含2×2個子圖的圖像
Aexs是軸(Axis)的復數(shù),翻譯為軸系、坐標系,可以將其理解為整個圖像(Figure)的一個子圖,一個圖形可以包含多個子圖,我們在子圖中進行具體圖表的繪制。通過plt.plot()函數(shù)可以創(chuàng)建子圖對象,通過set_title()可以設置子圖的標題,set_xlabel()、set_ylabel()對圖的橫縱坐標的標簽進行設置。
Axis指具體的坐標軸,其中trick代表坐標軸的刻度,通過Location對象控制刻度的位置,F(xiàn)ormatter格式化刻度顯示的字符串,通過這兩個對象可以精確地控制刻度的顯示。
Artist對象:在圖像中任何元素都可以看作Artist,包括2D線條(Line)、文本、以及Axis和圖像Figure,當圖片被渲染時,這些對象被繪制到圖片中。大多數(shù)Artist對象綁定于一個具體軸Axis,這樣的對象不可以在軸系之間共享。
matplot的輸入數(shù)據(jù)最好轉(zhuǎn)化為np.array類型,使用其他的數(shù)據(jù)類型例如np.matrix、pandas等可能會報錯,因此在傳入?yún)?shù)前先將其他類型通過numpy轉(zhuǎn)換一下。
matplotlib建議的引入必要庫與編碼方式如下,繪圖時首先通過plt接口創(chuàng)建Figure對象與子圖對象ax,之后通過ax調(diào)用函數(shù)繪圖,通過定義函數(shù)來進行圖像繪制可以避免許多重復操作,而且便于代碼維護。例如下面定義了my_plotter()完成圖像繪制,傳入子圖ax,兩個數(shù)據(jù)data1,data2,以及圖像繪制參數(shù)param_dic。
import matplotlib.pyplot as plt # 引入必要的庫 import numpy as np %matplotlib inline # 定義函數(shù)進行圖像繪制操作 def my_plotter(ax,data1,data2,param_dic): ax.plot(x, y,**param_dic) x = np.arange(0, 10, 0.2) # 準備數(shù)據(jù) y = np.sin(x) fig, ax = plt.subplots(1) # 創(chuàng)建子圖 my_plotter(ax,x, y,{ 'linestyle':'dashed','label':'sinx'}) # 調(diào)用函數(shù)繪制圖像
2、基本用法
創(chuàng)建圖像并繪制函數(shù)
首先需要導入必須的函數(shù)庫matplotlib.pyplot與numpy。如果使用jupyternotebook則需要添加%matplotlib inline設置以顯示圖片
通過plt.figure()創(chuàng)建一個圖像,其中num屬性指出顯示圖像的窗口,figsize屬性可以指定圖像的大小,facecolor屬性指定圖像的背景顏色。
通過plt.plot()進行曲線的繪制,前兩個數(shù)組參數(shù)為圖像x、y的坐標值。之后的可選參數(shù)對可以對線條的顏色(color)、寬度(linewidth)、樣式(linestyle)、不透明度(alpha)進行設置
plt.scatter()繪制單獨的一個點,而不是連起來的曲線,同樣前兩個參數(shù)為數(shù)組,對應點的x、y坐標。屬性s設置點的大小,color設置顏色
最后通過plt.show()輸出圖像,或者通過plt.savefig()保存為指定圖片,注意要在show()之前使用,否則圖片會被輸出,從而保存的圖片為空。
如果需要頻繁進行繪圖,則需要關閉一些沒用的圖片以節(jié)約內(nèi)存。通過plt.cla()可以關閉當前Axes,plt.clf()關閉當前圖像,plt.close()關閉當前繪圖窗口。
import numpy as np import matplotlib.pyplot as plt # 設置行內(nèi)顯示 %matplotlib inline x = np.linspace(-5, 5, 50) # 在-5~5內(nèi)均勻取50個數(shù) y1 = 2*x + 1 # 定義一個線性函數(shù) y2 = x**2 # 定義一個二次函數(shù) plt.figure(num=3, figsize=(10, 5), facecolor='white') # 創(chuàng)建一個圖形對象 plt.plot(x, y2, alpha=0.5) # 繪制曲線 plt.plot(x, y1, color='red', linewidth=1.0, linestyle='--') plt.scatter([1],[1],s=200,color='orange') # 繪制一個點 plt.savefig('./myplt.jpg') # 保存圖片 plt.show() # 顯示圖像 plt.close() # 關閉繪圖窗口
調(diào)整坐標軸
通過plt.xlim可以調(diào)整x坐標軸的范圍,plt.xlabel設置坐標軸的名字,同理plt.ylim與ylabel對y軸進行設置。matlab中無法使用中文,需要對字符集進行設置。
plt.xticks()可以自定義坐標刻度,將刻度以數(shù)組的形式傳入,并且可以傳入自定義顯示的刻度值
設置坐標軸刻度的位置:通過axes對象.xaxis獲取到x軸,并通過set_ticks_position()方法來設置位置,可選位置有:top,bottom ,both,default,none,對應的y軸刻度有:left,right,both,default,none
# 設置行內(nèi)顯示 %matplotlib inline plt.rcParams['font.sans-serif'] = ['SimHei'] # 設置字符集顯示中文 plt.rcParams['axes.unicode_minus'] = False # 設置負號正確顯示 x = np.linspace(-5, 5, 50) y1 = 2*x + 1 y2 = x**2 plt.figure(num=3, figsize=(10, 5)) plt.plot(x, y2) plt.plot(x, y1, color='red', linewidth=1.0, linestyle='--') plt.xlabel('x軸') # 設置顯示x軸標簽 plt.xlim(-2,2) # 設置x軸的范圍為-2~2 plt.xticks([-2,-1,0,1,2]) # 設置x軸刻度 axes=plt.gca() axes.xaxis.set_ticks_position('top') # 設置x坐標顯示在上邊框 plt.ylabel('y軸') plt.ylim(-5,5) # 設置y軸的范圍為-5~5 plt.yticks([-3,-1,0,1,3],['低','較低','中等','高','較高']) # 自定義刻度值 axes.yaxis.set_ticks_position('left') # 設置y坐標顯示在左邊框
我們還可以對圖片的四個邊框進行設置,通過plt.gca()獲取軸系對象axes,通過.spines['right']獲取右邊框,之后可以set_color來設置其顏色,用set_position()來設置邊框位置
axes.spines['right'].set_color('none') # 獲取并設置右邊框透明 axes.spines['top'].set_color('none') axes.spines['bottom'].set_position(('data', 0)) # 將底部邊框放到x=0的位置 axes.spines['left'].set_position(('data',0)) # 將左邊框放到y(tǒng)=0的位置
3、圖例和標注
在使用plt.plot()進行函數(shù)繪制時可以添加label屬性來定義曲線的名稱。
通過plt.legend()在圖片中顯示圖例,其loc屬性定義圖例的位置,值有'best' : 0,'upper right' : 1, 'upper left' : 2, 'lower left' : 3, 'lower right' : 4, 'right' : 5, 'center left' : 6, 'center right' : 7, 'lower center' : 8, 'upper center' : 9, 'center' : 10,其中best代表自動分配最佳位置
plt.plot(x, y1, label='linear') plt.plot(x, y2, color='red', linewidth=1.0, linestyle='--', label='square') plt.legend(loc='upper right')
也可以將plot()結(jié)果保存為l1,l2對象,再傳入legend函數(shù)中的handles屬性,這樣legend函數(shù)可以對圖中指定的線條對象添加圖例,并通過labels屬性設置圖例的內(nèi)容
l1, = plt.plot(x, y1) l2, = plt.plot(x, y2, color='red', linewidth=1.0, linestyle='--') # 對指定線條對象添加圖例 plt.legend(handles=[l1,l2,], labels=['linear','square'], loc='best')
通過plt.annotate()函數(shù)在圖片中添加注釋,第一個參數(shù)為注釋的內(nèi)容,fontsize注釋大小,xycoords表示注釋點的位置的表示方式,data代表根據(jù)數(shù)據(jù),xy代表傳入的數(shù)據(jù),textcoords='offset points'代表注釋的位置為根據(jù)點偏移,xytext設置偏移值,arrowprops以dict方式傳入箭頭的類型和弧度屬性
通過plt.text()在圖片中添加文本,前兩個參數(shù)為文本的位置,第三個參數(shù)為文本內(nèi)容,fontdict對文本字體、顏色進行設置,ha='center'設置居中對齊,va='bottom'設置向底部對其
plt.scatter([1],[1],s=100,color='orange') # 添加自定義注釋 plt.annotate('x2=2x-1',fontsize=20,xycoords='data',xy=(1,1), textcoords='offset points',xytext=(20,-30), arrowprops=dict(arrowstyle='->',connectionstyle='arc3,rad=.2')) # 添加文本 plt.text(0.5,-1,"This is a text",fontdict={'size':15,'color':'green'},ha='center', va='top')
4、繪制圖像 散點圖
通過scatter()繪制散點圖,s屬性為點的大小,c為點的顏色,alpha點的不透明度,marker指定點的形狀
散點圖
n = 1024 # data size X = np.random.normal(0, 1, n) # 每一個點的X值 Y = np.random.normal(0, 1, n) # 每一個點的Y值 C = np.arctan2(Y,X) # 為每個點生成顏色 plt.scatter(X, Y, s=75, c=C, alpha=0.5, marker='o') plt.show()
條形圖
通過plt.bar()函數(shù)繪制條形圖,前兩個參數(shù)傳入柱狀圖的x位置和y的值的數(shù)組,facecolor屬性設置主題顏色,edgecolor設置邊框顏色
n = 10 X = np.arange(n) # X取1~12 Y1 = np.array([8,9,12,6,5,10,11,13,4,2]) Y2 = np.array([5,6,8,3,14,10,3,2,1,4]) plt.bar(X, Y1, facecolor='blueviolet', edgecolor='orange') plt.bar(X, -Y2) # 在柱狀圖頂部添加文本標注 for x, y in zip(X, Y1): plt.text(x, y , y, ha='center', va='bottom') plt.show()
如上右圖所示,通過plt.hist(data)可以繪制數(shù)據(jù)的統(tǒng)計分布直方圖,參數(shù)bins指定劃分的統(tǒng)計區(qū)間,為數(shù)字時代表劃分為幾個區(qū)間,為數(shù)組時代表指定具體的區(qū)間。
plt.hist(data, bins=10) # 劃分區(qū)間的個數(shù) plt.hist(data, bins=[0, 500, 1000, 1500, 2000, 2500, 3000]) # 指定具體分組區(qū)間
等高線圖
等高線的數(shù)據(jù)是三維數(shù)據(jù),X,Y為自變量,Z為因變量函數(shù)值,根據(jù)函數(shù)值的不同顯示相同的值作為等高線
通過plt.contourf()函數(shù)進行顏色的填充,前三個參數(shù)為對應地X、Y、Z的值,cmap為填充的顏色,這里使用了matlabplot提供的一個顏色映射方案,根據(jù)值的由小到大映射為從藍到紅色
plt.contour()進行等高線的繪制,colors='black'線條顏色為黑色,linewidth=.5線條寬度為0.5
通過clabel()繪制文本,inline將文本填充到線條內(nèi)
通過colorbar()函數(shù)可以為圖片添加一個函數(shù)值對應顏色條
n = 256 x = np.linspace(-3, 3, n) y = np.linspace(-3, 3, n) X,Y = np.meshgrid(x, y) # 編制為256×256的網(wǎng)格,并把對應的坐標值返回給X、Y數(shù)組 def fun(x,y): # 定義函數(shù)值Z,是一個三維函數(shù)橢圓拋物面 return x**2+y**2 F = plt.contourf(X, Y, fun(X, Y), 8, alpha=.75,cmap='RdBu') # 進行顏色填充 C = plt.contour(X, Y, fun(X, Y), 8, colors='black', linewidth=.5) # 繪制等高線 plt.clabel(C, inline=True, fontsize=10) # 標注文本 plt.colorbar(F) # 添加一個colorbar plt.show()
三維圖像
在繪制3D圖形前需要額外引入一個包Axes3D,通過它來將當前的圖像轉(zhuǎn)化為3D圖
同樣3D圖需要三維數(shù)據(jù),X、Y編制為網(wǎng)格是自變量,Z是函數(shù)值
通過plt.plot_surface()繪制3D圖形,屬性rstride 和 cstride 分別代表 row 和 column 的跨度,跨度越小,圖形上的網(wǎng)格越密集,cmap為函數(shù)值的配色映射方案
通過等高線的繪制函數(shù)plt.contour()可以為3D圖形在平面繪制投影,zdir='z'代表沿著Z軸進行投影,這樣投影會出現(xiàn)在X-Y平面上,offset代表投影的偏移位置
import matplotlib.pyplot as plt import numpy as np from mpl_toolkits.mplot3d import Axes3D #引入3D繪圖庫 %matplotlib inline fig = plt.figure() ax = Axes3D(fig) # 將當前圖像轉(zhuǎn)化為3D X = np.arange(-10, 10, 0.5) Y = np.arange(-10, 10, 0.5) X, Y = np.meshgrid(X, Y) # 編制 X-Y 平面的網(wǎng)格 Z = np.sqrt(X ** 2 + Y ** 2) # Z值,定義為拋物面圖形 ax.plot_surface(X, Y, Z, rstride=1, cstride=1, cmap='hsv') # 繪制3D圖 ax.contourf(X, Y, Z, zdir='z', offset=0, cmap='hsv') # 添加沿Z軸方向的投影 plt.show()
繪制動畫
繪制動畫需要從matplotlib中額外引入animation庫
之后先繪制其中一幀的圖像,比如這里要繪制sinx的動畫,先在0~2Π取自變量x數(shù)組,再繪制其sinx的曲線line
接著定義動畫初始幀的顯示函數(shù)init(),返回初始的line對象。然后定義其每一幀的圖像顯示函數(shù)animate,其參數(shù)i代表第i幀,根據(jù)i返回不同的line對象。
最后通過animation.FuncAnimation()繪制圖像,其參數(shù)fig為之前創(chuàng)建的圖片對象,init_func為初始化顯示函數(shù),func為每一幀的顯示函數(shù),interval為更新頻率(單位ms),frames為動畫一共有多少幀,blit為True代表每次只更新有變化的點
最后將返回的ani對象的save()方法將其保存為gif,這里使用的writer為imagemagick
import numpy as np from matplotlib import pyplot as plt from matplotlib import animation # 引入動畫庫 %matplotlib inline fig,ax=plt.subplots() # 創(chuàng)建畫布 x=np.arange(0,2*np.pi,0.01) # 從0~2Π每隔0.01取一個數(shù) line,=ax.plot(x,np.sin(x)) # 繪制sinx的圖像 def init(): # 定義初始幀顯示函數(shù) line.set_ydata(np.sin(x)) return line, def animate(i): # 定義每一幀的顯示函數(shù) line.set_ydata(np.sin(x+i/10)) return line, # 繪制動畫 ani=animation.FuncAnimation(fig=fig,init_func=init,func=animate,interval=20,frames=100,blit=True) ani.save('sinx.gif',writer='imagemagick') # 保存動畫為gif plt.show()
5、多張圖片
通過plt.subplot()可以劃分為多個子圖并選中其中的某個位置,例如subplot(2,2,1)代表創(chuàng)建2×2的子圖,并且選中其中的第一個子圖,也可以省略中間的逗號:subplot(224)代表選中2×2個子圖中的第四個。除了直接通過plt對象繪制子圖外,subplot可以返回子圖對象,可以通過子圖對象調(diào)用plot()來繪圖。
import matplotlib.pyplot as plt %matplotlib inline plt.figure() # 選中2×2子圖中的第一個并畫一條線 plt.subplot(2,2,1) plt.plot([0,1],[2,3]) # 選中2×2子圖的第四個畫一條線 ax2=plt.subplot(224) ax2.plt.plot([2,1],[3,4]) plt.show()
注意這里的劃分并不是真正的分割圖像,只是為了定位子圖而假定將整個圖像進行劃分。
例如下面的代碼首先將畫布認為2行1列選中第一塊,就是上面的一行大的,再將其認為2行3列選擇第四塊,那就是第二行的第一個。通過不同的劃分和選擇可以得到不同大小與不同位置的子圖。如果涉及到?jīng)_突的區(qū)域,后面的子圖會將之前的子圖覆蓋掉。
# 劃分為2行1列,選中第一塊 plt.subplot(2,1,1) plt.plot([0,1],[2,3]) # 劃分為2行3列,選中第四塊 plt.subplot(234) plt.plot([2,1],[3,4])
通過subplot2grid()方法可以更加方便的劃分和選擇子圖,如下所示subplot2grid((3, 3), (0, 0), colspan=3)表示將圖片分為3×3區(qū)域,從第0行0列開始,橫向跨越colspan列數(shù)為3,縱向跨越rowspan行數(shù)默認為1。
注意在一整張圖中可以通過title()、xlabel()、ylabel()來設置標題和坐標名,但是在子圖中需要在函數(shù)名之前加一個set_
ax1 = plt.subplot2grid((3, 3), (0, 0), colspan=3) ax1.plot([1, 2], [1, 2]) # 畫小圖 ax1.set_title('ax1_title') # 設置小圖的標題 ax2 = plt.subplot2grid((3,3), (2,1),colspan=2) ax2.plot([2,1],[1,0]) ax2.set_xlabel('ax2_x') # 設置小圖的坐標軸名 ax2.set_ylabel('ax2_y')
gridspec()函數(shù)可以讓我們像使用python數(shù)組那樣方便地選擇子圖區(qū)域。使用前先從matplotlib中引入該模塊,通過Gridspec()函數(shù)將圖像劃分為區(qū)域,然后返回gs對象,通過gs對象可以像數(shù)組那樣選擇子區(qū)域。例如gs[1, :2],逗號之前代表對行序號的選擇,如果只有一個數(shù)字代表選中全部序號為1的行,逗號之后為列,這里0:2代表選中從0到2列之前的所有列,其中從0開始可以省略。對應地如果選中指導結(jié)尾的話也可以省略,即gs[1, : ]。如果序號為-2,代表選中倒數(shù)第二個
import matplotlib.pyplot as plt import matplotlib.gridspec as gridspec # 引入庫 %matplotlib inline plt.figure() gs = gridspec.GridSpec(3, 3) # 將圖像劃分為3×3個區(qū)域 ax1 = plt.subplot(gs[0, :]) # 選中第0行,所有列 ax2 = plt.subplot(gs[-1, -2]) # 選中倒數(shù)第1行,倒數(shù)第2列 plt.show()
通過subplots()可以一次性創(chuàng)建并返回多個子圖對象,如下所示為劃分四個子圖并且依次返回給ax11~ax22四個對象,并且四個對象的位置不能亂。
其中sharex代表圖像共享X坐標軸。plt.tight_layout()代表緊湊顯示
f, ((ax11, ax12), (ax21, ax22)) = plt.subplots(2, 2, sharex=True, sharey=True) ax11.scatter([1,2], [1,2]) plt.tight_layout() plt.show()
畫中畫:通過figure對象的add_axes()可以在圖片中添加另一個圖片,其傳入的參數(shù)為圖片所在畫布的四個邊框的位置比例,返回創(chuàng)建的子圖對象ax,利用ax進行繪制
x=[0,1] y=[2,3] fig = plt.figure() ax1 = fig.add_axes([0.1, 0.1, 0.8, 0.8]) # 創(chuàng)建一個大圖對象 ax1.plot(x, y, 'r') # 大圖繪制 ax2 = fig.add_axes([0.2, 0.6, 0.25, 0.25]) # 創(chuàng)建小圖 ax2.plot(x, y, 'b') # 小圖繪制 plt.show()
子圖拷貝:通過子圖對象ax的twinx()函數(shù)可以在相同位置拷貝x軸相同的另一個重疊的ax對象,只不過y軸放到了對稱的位置,最后兩個子圖會重疊顯示
fig, ax1 = plt.subplots() ax2 = ax1.twinx() # 拷貝ax對象 ax1.plot([0,1], [2,3], 'g-') # 在原圖中繪制 ax1.set_xlabel('X data') ax1.set_ylabel('Y1 data', color='g') # 原圖的y軸在左側(cè) ax2.plot([0,1], [3,2], 'b-') # 拷貝對象中繪圖 ax2.set_ylabel('Y2 data', color='b') # 拷貝子圖的y軸在右側(cè) plt.show()
總結(jié)
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關文章
Python 利用scrapy爬蟲通過短短50行代碼下載整站短視頻
近日,有朋友向我求助一件小事兒,他在一個短視頻app上看到一個好玩兒的段子,想下載下來,可死活找不到下載的方法。經(jīng)過我的一番研究才找到解決方法,下面小編給大家分享Python 利用scrapy爬蟲通過短短50行代碼下載整站短視頻的方法,感興趣的朋友一起看看吧2018-10-10Python使用mongodb保存爬取豆瓣電影的數(shù)據(jù)過程解析
這篇文章主要介紹了Python使用mongodb保存爬取豆瓣電影的數(shù)據(jù)過程解析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下2019-08-08Pytorch中的 torch.distributions庫詳解
這篇文章主要介紹了Pytorch中的 torch.distributions庫,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2023-02-02python數(shù)據(jù)類型的詳細分析(附示例代碼)
這篇文章主要給大家介紹了關于python數(shù)據(jù)類型分析的相關資料,python里可以通過type()函數(shù)來查看數(shù)據(jù)類型,文中通過示例代碼介紹的非常詳細,需要的朋友可以參考下2021-09-09pytorch神經(jīng)網(wǎng)絡之卷積層與全連接層參數(shù)的設置方法
今天小編就為大家分享一篇pytorch神經(jīng)網(wǎng)絡之卷積層與全連接層參數(shù)的設置方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-08-08python連接clickhouse數(shù)據(jù)庫的兩種方式小結(jié)
這篇文章主要介紹了python連接clickhouse數(shù)據(jù)庫的兩種方式小結(jié),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-05-05Python 利用pandas和mysql-connector獲取Excel數(shù)據(jù)寫入到MySQL數(shù)據(jù)庫
在實際應用中,我們可能需要將Excel表格中的數(shù)據(jù)導入到MySQL數(shù)據(jù)庫中,以便于進行進一步的數(shù)據(jù)分析和處理,本文將介紹如何使用Python將Excel表格中的數(shù)據(jù)插入到MySQL數(shù)據(jù)庫中,需要的朋友可以參考下2023-10-10