1.基礎用法
??Matplotlib提出了Object Container(對象容器)的概念,它有Figure、Axes、Axis、Tick四種類型的對象容器。Figure負責圖形大小、位置等操作;Axes負責坐標軸位置、繪圖等操作 ;Tick負責格式化刻度的樣式等操作;四種對象容器之間是層層包含的關系。
??Matplotlib.pyplot模塊畫折線圖的plot函數(shù)的常用語法和參數(shù)含義如下:
plot(x,y,s)
??plot函數(shù)也可以使用如下調(diào)用格式:
plot(x, y, linestyle, linewidth, color, marker, markersize, markeredgecolor, markerfacecolor, markeredgewidth, label, alpha)
linestyle:指定折線的類型,可以是實線、虛線和點畫線等,默認為實線。
linewidth:指定折線的寬度。
marker:可以為折線圖添加點,該參數(shù)設置點的形狀。
markersize:設置點的大小。
markeredgecolor:設置點的邊框色。
markerfacecolor:設置點的填充色。
markeredgewidth:設置點的邊框寬度。
label:添加折線圖的標簽,類似于圖例的作用。
alpha:設置圖形的透明度。

??Matplotlib.pyplot模塊其他常用函數(shù)有:
(1)pie():繪制餅狀圖。
(2)bar():繪制柱狀圖。
(3)hist():繪制二維直方圖。
(4)scatter():繪制散點圖。

??Matplotlib繪圖主要包括以下幾個步驟:
(1)導入Matplotlib.pyplot模塊。
(2)設置繪圖的數(shù)據(jù)及參數(shù)。
(3)調(diào)用Matplotlib.pyplot模塊的plot()、pie()、bar()、hist()、scatter()等函數(shù)進行繪圖。

??注意模塊加載的兩種方式:
①import matplotlib.pyplot as plt或from matplotlib import pyplot as plt
畫圖函數(shù)調(diào)用為plt.plot()等。
②from matplotlib.pyplot import *
畫圖函數(shù)調(diào)用為plot()等。
為了將而向對象的繪圖庫包裝成只使用函數(shù)的API,pyplot模塊的內(nèi)部保存了當前圖形以及當前子圖等信息??梢允褂?code>gcf()和gca()獲得這兩個對象,它們分別是“Get Current Figure”和“Get Current Axes”開頭字母的縮寫。gcf()獲得的是表示圖形的Figure對象,而gca()獲得的則是表示子圖的Axes對象。例如:
fig = gcf()
axes = gca()
例2.36 畫出例2.33中三個用戶十天消費總額的柱狀圖
#程序文件Pex2_36.py
import numpy as np, pandas as pd
from matplotlib.pyplot import *
a=pd.read_excel("Pdata2_33.xlsx",usecols=range(1,4)) #提取第2列到第4列的數(shù)據(jù)
c=np.sum(a) #求每一列的和
ind=np.array([1,2,3]); width=0.2
rc('font',size=16); bar(ind,c,width); ylabel("消費數(shù)據(jù)")
xticks(ind,['用戶A','用戶B','用戶C'],rotation=20) #旋轉20度
rcParams['font.sans-serif']=['SimHei'] #用來正常顯示中文標簽
savefig('figure2_36.png',dpi=500) #保存圖片為文件figure2_36.png,像素為500
show()

注2.6
Matplotlib畫圖顯示中文時通常為亂碼,如果想在圖形中顯示中文字符、負號等,則需要使用如下代碼進行設置。
rcParams['font.sans-serif']=['SimHei'] #用來正常顯示中文標簽
rcParams['axes.unicode_minus']=False #用來正常顯示負號
或者等價地寫為:
rc('font',family='SimHei') #用來正常顯示中文標簽
rc('axes',unicode_minus=False) #用來正常顯示負號
2.Matplotlb.pyplot的可視化應用
Matplotlib工具庫依賴于NumPy等工具庫,可以繪制多種形式的圖形,是計算結果可視化的重要工具,下面給出一些可視化示例。
2.1散點圖

#程序文件Pex2_37.py
import numpy as np
from matplotlib.pyplot import *
x=np.array(range(8))
y='27.0 26.8 26.5 26.3 26.1 25.7 25.3 24.8' #數(shù)據(jù)是粘貼過來的
y=",".join(y.split()) #把空格替換成逗號
y=np.array(eval(y)) #數(shù)據(jù)之間加逗號太麻煩,我們用程序轉換
scatter(x,y)
savefig('figure2_23.png',dpi=500); show()

2.2多個圖形顯示在一個圖形畫面

#程序文件Pex2_38.py
import numpy as np
from matplotlib.pyplot import *
x=np.linspace(0,2*np.pi,200)
y1=np.sin(x); y2=np.cos(pow(x,2))
rc('font',size=16); rc('text', usetex=True) #調(diào)用tex字庫
plot(x,y1,'r',label='$sin(x)$',linewidth=2) #Latex格式顯示公式
plot(x,y2,'b--',label='$cos(x^2)$')
xlabel('$x$'); ylabel('$y$',rotation=0)
savefig('figure2_38.png',dpi=500); legend(); show()


2.3多個圖形單獨顯示

#程序文件Pex2_39.py
import numpy as np
from matplotlib.pyplot import *
x=np.linspace(0,2*np.pi,200)
y1=np.sin(x); y2=np.cos(x); y3=np.sin(x*x)
rc('font',size=16); rc('text', usetex=True) #調(diào)用tex字庫
ax1=subplot(2,2,1) #新建左上1號子窗口
ax1.plot(x,y1,'r',label='$sin(x)$') #畫圖
legend() #添加圖例
ax2=subplot(2,2,2) #新建右上2號子窗口
ax2.plot(x,y2,'b--',label='$cos(x)$'); legend()
ax3=subplot(2,1,2) #新建兩行、1列的下面子窗口
ax3.plot(x,y3,'k--',label='$sin(x^2)$'); legend();
savefig('figure2_39.png',dpi=500); show()

2.4三維空間的曲線

#程序文件Pex2_40.py
from mpl_toolkits import mplot3d
import matplotlib.pyplot as plt
import numpy as np
ax=plt.axes(projection='3d') #設置三維圖形模式
z=np.linspace(0, 100, 1000)
x=np.sin(z)*z; y=np.cos(z)*z
ax.plot3D(x, y, z, 'k')
plt.savefig('figure2_40.png',dpi=500); plt.show()

2.5三維曲面圖形

#程序文件Pex2_41.py
from mpl_toolkits import mplot3d
import matplotlib.pyplot as plt
import numpy as np
x=np.linspace(-6,6,30)
y=np.linspace(-6,6,30)
X,Y=np.meshgrid(x, y)
Z= np.sin(np.sqrt(X ** 2 + Y ** 2))
ax1=plt.subplot(1,2,1,projection='3d')
ax1.plot_surface(X, Y, Z,cmap='viridis')
ax1.set_xlabel('x'); ax1.set_ylabel('y'); ax1.set_zlabel('z')
ax2=plt.subplot(1,2,2,projection='3d');
ax2.plot_wireframe(X, Y, Z,color='c')
ax2.set_xlabel('x'); ax2.set_ylabel('y'); ax2.set_zlabel('z')
plt.savefig('figure2_41.png',dpi=500); plt.show()

2.6等高線圖


(1)畫出該區(qū)域的等高線.
(2)畫出該區(qū)域的三維表面圖.
畫等高線及三維表面圖的程序如下:
#程序文件Pex2_42_1.py
from mpl_toolkits import mplot3d
import matplotlib.pyplot as plt
import numpy as np
z=np.loadtxt("Pdata2_42.txt") #加載高程數(shù)據(jù)
x=np.arange(0,1500,100)
y=np.arange(1200,-10,-100)
contr=plt.contour(x,y,z); plt.clabel(contr) #畫等高線并標注
plt.xlabel('$x$'); plt.ylabel('$y$',rotation=0)
plt.savefig('figure2_42_1.png',dpi=500)
plt.figure() #創(chuàng)建一個繪圖對象
ax=plt.axes(projection='3d') #用這個繪圖對象創(chuàng)建一個三維坐標軸對象
X,Y=np.meshgrid(x,y)
ax.plot_surface(X, Y, z,cmap='viridis')
ax.set_xlabel('x'); ax.set_ylabel('y'); ax.set_zlabel('z')
plt.savefig('figure2_42_2.png',dpi=500); plt.show()

#程序文件Pex2_43.py
import matplotlib.pyplot as plt
from numpy import *
x=linspace(0,15,11); y=linspace(0,10,12)
x,y=meshgrid(x,y) #生成網(wǎng)格數(shù)據(jù)
v1=y*cos(x); v2=y*sin(x)
plt.quiver(x,y,v1,v2)
plt.savefig('figure2_43.png',dpi=500); plt.show()

3.可視化的綜合應用



#程序文件Pex2_34.py
import numpy as np
from matplotlib.pyplot import *
x=np.linspace(0,2*np.pi,200)
y1=np.sin(x); y2=np.cos(x); y3=np.sin(x*x); y4=x*np.sin(x)
rc('font',size=16); rc('text', usetex=True) #調(diào)用tex字庫
ax1=subplot(2,3,1) #新建左上1號子窗口
ax1.plot(x,y1,'r',label='$sin(x)$') #畫圖
legend() #添加圖例
ax2=subplot(2,3,2) #新建2號子窗口
ax2.plot(x,y2,'b--',label='$cos(x)$'); legend()
ax3=subplot(2,3,(3,6)) #3、6子窗口合并
ax3.plot(x,y3,'k--',label='$sin(x^2)$'); legend()
ax4=subplot(2,3,(4,5)) #4、5號子窗口合并
ax4.plot(x,y4,'k--',label='$xsin(x)$'); legend()
savefig('figure2_44.png',dpi=500); show()

例2.45 給定某集市2009.1.1~2012.12.30商品交易的8568條數(shù)據(jù)(文件名Trade.xlsx),格式如圖2.13所示,對其中的一些數(shù)據(jù)特征進行可視化。

#程序文件Pex2_45.py
import numpy as np
import pandas as pd
from matplotlib.pyplot import *
a=pd.read_excel("Trade.xlsx")
a['year']=a.Date.dt.year #添加交易年份字段
a['month']=a.Date.dt.month #添加交易月份字段
rc('font',family='SimHei') #用來正常顯示中文標簽
ax1=subplot(2,3,1) #建立第一個子圖窗口
Class_Counts=a.Order_Class[a.year==2012].value_counts()
Class_Percent=Class_Counts/Class_Counts.sum()
ax1.set_aspect(aspect='equal') #設置縱橫軸比例相等
ax1.pie(Class_Percent,labels=Class_Percent.index,
autopct="%.1f%%") #添加格式化的百分比顯示
ax1.set_title("2012年各等級訂單比例")
ax2=subplot(232) #建立第2個子圖窗口
#統(tǒng)計2012年每月銷售額
Month_Sales=a[a.year==2012].groupby(by='month').aggregate({'Sales':np.sum})
#下面使用Pandas畫圖
Month_Sales.plot(title="2012年各月銷售趨勢",ax=ax2, legend=False)
ax2.set_xlabel('')
ax3=subplot(2,3,(3,6))
cost=a['Trans_Cost'].groupby(a['Transport'])
ts = list(cost.groups.keys())
dd = np.array(list(map(cost.get_group, ts)))
boxplot(dd); gca().set_xticklabels(ts)
ax4=subplot(2,3,(4,5))
hist(a.Sales[a.year==2012],bins=40, density=True)
ax4.set_title("2012年銷售額分布圖");
ax4.set_xlabel("銷售額");
savefig("figure2_45.png"); show()
注2.8 畫子圖ax3的幾條語句,等價于下列語句:
cost=a['Trans_Cost'].groupby(a['Transport'])
d1=cost.get_group('大卡'); d2=cost.get_group('火車'); d3=cost.get_group('空運');
dd=np.array([d1,d2,d3])
boxplot(dd); gca().set_xticklabels(['大卡','火車','空運'])
上面程序中還涉及很多新內(nèi)容,如日期數(shù)據(jù)的處理、數(shù)據(jù)的分組和聚合等,希望讀者自己用心去體會。所畫的圖形如圖2.14所示。
