Python有很多可視化工具,本篇只介紹Matplotlib。
Matplotlib是一種2D的繪圖庫,它可以支持硬拷貝和跨系統的交互,它可以在Python腳本、IPython的交互環境下、Web應用程序中使用。該項目是由John Hunter於2002年啟動的,其目的是為Python構建一個MATLAB式的繪圖接口。如果結合使用一種GUI工具包(如IPython),Matplotlib還具有諸如縮放和平移等交互功能。它不僅支持各種操作系統上許多不同的GUI后端,而且還能將圖片導出為各種常見的食量(vector)和光柵(raster)圖:PDF、SVG、JPG、PNG、BMP、GIF等。
Matplotlib程序包
所謂“一圖勝千言”,我們很多時候需要通過可視化的方式查看、分析數據,雖然Pandas中也有一些繪圖操作,但是相比較而言,Matplotlib在繪圖顯示效果方面更加出色。Python為Matplotlib提供了一個方便的接口,我們可以通過Pyplot對Matplotlib進行操作,多數情況下,Pyplot的命令與MATLAB有些相似。
導入Matplotlib包進行簡單的操作(此處需要安裝pip install matplotlib):
import matplotlib.pyplot as plt#約定俗成的寫法plt #首先定義兩個函數(正弦&余弦) import numpy as np X=np.linspace(-np.pi,np.pi,256,endpoint=True)#-π to+π的256個值 C,S=np.cos(X),np.sin(X) plt.plot(X,C) plt.plot(X,S) #在ipython的交互環境中需要這句話才能顯示出來 plt.show()
輸出結果:
繪圖命令的基本架構及其屬性設置
上面的例子我們可以看出,幾乎所有的屬性和繪圖的框架我們都選用默認設置。現在我們來看Pyplot繪圖的基本框架是什么,用過Photoshop的人都知道,作圖時先要定義一個畫布,此處的畫布就是Figure,然后再把其他素材“畫”到該Figure上。
1)在Figure上創建子plot,並設置屬性
x=np.linspace(0,10,1000)#X軸數據 y1=np.sin(x)#Y軸數據 y2=np.cos(x**2)#Y軸數據 x**2即x的平方 plt.figure(figsize=(8,4)) plt.plot(x,y1,label="$sin(x)$",color="red",linewidth=2)#將$包圍的內容渲染為數學公式 plt.plot(x,y2,"b--",label="$cos(x^2)$") #指定曲線的顏色和線性,如‘b--’表示藍色虛線(b:藍色,-:虛線) plt.xlabel("Time(s)") plt.ylabel("Volt") plt.title("PyPlot First Example") ''' 使用關鍵字參數可以指定所繪制的曲線的各種屬性: label:給曲線指定一個標簽名稱,此標簽將在圖標中顯示。如果標簽字符串的前后都有字符'$',則Matplotlib會使用其內嵌的LaTex引擎將其顯示為數學公式 color:指定曲線的顏色。顏色可以用如下方法表示 英文單詞 以‘#’字符開頭的3個16進制數,如‘#ff0000’表示紅色。 以0~1的RGB表示,如(1.0,0.0,0.0)也表示紅色。 linewidth:指定權限的寬度,可以不是整數,也可以使用縮寫形式的參數名lw。 ''' plt.ylim(-1.5,1.5) plt.legend()#顯示左下角的圖例 plt.show()
2)在Figure上創建多個子plot
如果需要繪制多幅圖表的話,可以給Figure傳遞一個整數參數指定圖表的序號,如果所指定序號的繪圖對象已經存在的話,將不創建新的對象,而只是讓它成為當前繪圖對象。
fig1=plt.figure(2) plt.subplot(211) #subplot(211)把繪圖區域等分為2行*1列共兩個區域,然后在區域1(上區域)中創建一個軸對象 plt.subplot(212)#在區域2(下區域)創建一個軸對象 plt.show()
輸出結果:
我們還可以通過命令再次拆分這些塊(相當於Word中拆分單元格操作)
f1=plt.figure(5)#彈出對話框時的標題,如果顯示的形式為彈出對話框的話 plt.subplot(221) plt.subplot(222) plt.subplot(212) plt.subplots_adjust(left=0.08,right=0.95,wspace=0.25,hspace=0.45) # subplots_adjust的操作時類似於網頁css格式化中的邊距處理,左邊距離多少? # 右邊距離多少?這取決於你需要繪制的大小和各個模塊之間的間距 plt.show()
輸出結果:
3)通過Axes設置當前對象plot的屬性
以上我們操作的是在Figure上繪制圖案,但是當我們繪制圖案過多,又需要選取不同的小模塊進行格式化設置時,Axes對象就能很好地解決這個問題。
fig,axes=plt.subplots(nrows=2,ncols=2)#定一個2*2的plot plt.show()
輸出結果:
現在我們需要通過命令來操作每個plot(subplot),設置它們的title並刪除橫縱坐標值。
fig,axes=plt.subplots(nrows=2,ncols=2)#定一個2*2的plot axes[0,0].set(title='Upper Left') axes[0,1].set(title='Upper Right') axes[1,0].set(title='Lower Left') axes[1,1].set(title='Lower Right') # 通過Axes的flat屬性進行遍歷 for ax in axes.flat: # xticks和yticks設置為空置 ax.set(xticks=[],yticks=[]) plt.show()
輸出結果:
另外,實際來說,plot操作的底層操作就是Axes對象的操作,只不過如果我們不使用Axes而用plot操作時,它默認的是plot.subplot(111),也就是說plot其實是Axes的特例。
4)保存Figure對象
最后一項操作就是保存,我們繪圖的目的是用在其他研究中,或者希望可以把研究結果保存下來,此時需要的操作時save。
plt.savefig(r"C:\Users\123\Desktop\save_test.png",dpi=520)#默認像素dpi是80
很明顯保存的像素越高,內存越大。此處只是用了savefig屬性對Figure進行保存。
另外,除了上述的基本操作之外,Matplotlib還有其他的繪圖優勢,此處只是簡單介紹了它在繪圖時所需要注意的事項,更多的屬性設置請參考:https://matplotlib.org/api/
Seaborn模塊介紹
前面我們簡單介紹了Matplotlib庫的繪圖功能和屬性設置,對於常規性的繪圖,使用Pandas的繪圖功能已經足夠了,但如果對Matplotlib的API屬性研究較為透徹,幾乎沒有不能解決的問題。但是Matplotlib還是有它的不足之處,Matplotlib自動化程度非常高,但是,掌握如何設置系統以便獲得一個吸引人的圖是相當困難的事。為了控制Matplotlib圖表的外觀,Seaborn模塊自帶許多定制的主題和高級的接口。
1)未加Seaborn模塊的效果
import numpy as np import matplotlib as mpl import matplotlib.pyplot as plt np.random.seed(sum(map(ord,"aesthetics"))) #首先定義一個函數用來畫正弦函數,可幫助了解可以控制的不同風格參數 def sinplot(flip=1): x=np.linspace(0,14,100) for i in range(1,7): plt.plot(x,np.sin(x+i*0.5)*(7-i)*flip) sinplot() plt.show()
輸出結果:
2)加入Seaborn模塊的效果
import numpy as np import matplotlib as mpl import matplotlib.pyplot as plt # 添加了Seaborn模塊 np.random.seed(sum(map(ord,"aesthetics"))) #首先定義一個函數用來畫正弦函數,可幫助了解可以控制的不同風格參數 def sinplot(flip=1): x=np.linspace(0,14,100) for i in range(1,7): plt.plot(x,np.sin(x+i*0.5)*(7-i)*flip) #轉換成Seaborn模塊,只需要引入seaborn模塊 import seaborn as sns#添加Seaborn模塊 sinplot() plt.show()
輸出效果:
小編使用的jupyter notebook編輯器,使用與不使用Seaborn模塊效果差別不明顯。
使用Seaborn的優點有:
- Seaborn默認淺灰色背景與白色網格線的靈感來源於Matplotlib,卻比Matplotlib的顏色更加柔和
- Seaborn把繪圖風格參數與數據參數分開設置。
其中,Seaborn有兩組函數對風格進行控制:axes_style()/set_style()函數和plotting_context()/set_context()函數。
axes_style()函數和plotting_context()函數返回參數字典,set_style()函數和set_context()函數設置Matplotlib。
使用set_style()函數
import seaborn as sns ''' Seaborn有5種預定義的主題: darkgrid(灰色背景+白網格) whitegrid(白色背景+黑網格) dark(僅灰色背景) white(僅白色背景) ticks(坐標軸帶刻度) 默認的主題是darkgrid,修改主題可以使用set_style函數 ''' sns.set_style("whitegrid") sinplot()#即上段代碼中定義的函數 plt.show()
輸出結果:
使用set_context()函數
''' 上下文(context)可以設置輸出圖片的大小尺寸(scale) Seaborn中預定義的上下文有4種:paper、notebook、talk和poster 默認使用notebook上下文 ''' sns.set_context("poster") sinplot()#即前文定義的函數 plt.show()
輸出結果:
使用Seaborn“耍酷”
然而Seaborn不僅能夠用來更改背景顏色,或者改變畫布大小,還有其他很多方面的用途,比如下面的例子。
''' Annotated heatmaps ================================ ''' import matplotlib.pyplot as plt import seaborn as sns sns.set() #通過加載sns自帶數據庫中的數據(具體數據可以不關心) flights_long=sns.load_dataset("flights") flights=flights_long.pivot("month","year","passengers") # 使用每個單元格中的數據值繪制一個熱力圖heatmap sns.heatmap(flights,annot=True,fmt="d",linewidths=.5) plt.show()
輸出結果:
描述性統計圖形概覽
描述性統計是借助圖表或者總結性的數值來描述數據的統計手段。數據挖掘工作的數據分析階段,我們可借助描述性統計來描繪或總結數據的基本情況,一來可以梳理自己的思維,而來可以更好地向他人展示數據分析結果。數值分析的過程中,我們往往要計算出數據的統計特征,用來做科學計算的Numpy和Scipy工具可以滿足我們的需求。Matplotlib工具可用來繪制圖,滿足圖分析的需求。
1)制作數據
數據是自己制作的,主要包括個人身高、體重及一年的借閱圖書量(之所以自己制作數據是因為不是每份真實的數據都可以進行接下來的分析,比如有些數據就不能繪制餅圖,另一個角度也說明,此處舉例的數據其實沒有實際意義,只是為了分析二舉例,但是不代表在具體的應用中這些分析不能發揮作用)。
另外,以下的數據顯示都是在Seaborn庫的作用下體現的效果。
# 案例分析 from numpy import array from numpy.random import normal def getData(): heights=[] weights=[] books=[] N=10000 for i in range(N): while True: #身高服從均值為172,標准差為6的正態分布 height=normal(172,6) if 0<height: break while True: #體重由身高作為自變量的線性回歸模型產生,誤差服從標准正態分布 weight=(height-80)*0.7+normal(0,1) if 0<weight: break while True: #借閱量服從均值為20,標准差為5的正態分布 number=normal(20,5) if 0<=number and number<=50: book='E' if number<10 else ('D' if number<15 else ('C' if number<20 else ('B' if number<25 else 'A'))) break heights.append(height) weights.append(weight) books.append(book) return array(heights),array(weights),array(books) heights,weights,books=getData()
2)頻數分析
(1)定性分析
柱狀圖和餅形圖是對定性數據進行頻數分析的常用工具,使用前需將每一類的頻數計算出來。
柱狀圖。柱狀圖是以柱的高度來指代某類型的頻數,使用Matplotlib對圖書借閱量這一定性變量繪制柱狀圖的代碼如下。(接上段代碼)
from matplotlib import pyplot #繪制柱狀圖 def drawBar(books): xticks=['A','B','C','D','E'] bookGroup={} #對每一類借閱量進行頻數統計 for book in books: bookGroup[book]=bookGroup.get(book,0)+1 #創建柱狀圖 #第一個參數為柱的橫坐標 #第二個參數為柱的高度 #參數align為柱的對齊方式,以第一個參數為參考標准 pyplot.bar(range(5),[bookGroup.get(xtick,0) for xtick in xticks],align='center') #設置柱的文字說明 #第一個參數為文字說明的橫坐標 #第二個參數為文字說明的內容 pyplot.xticks(range(5),xticks) #設置橫坐標的文字說明 pyplot.xlabel("Types of Students") #設置縱坐標的文字說明 pyplot.ylabel("Frequency") #設置標題 pyplot.title("Numbers of Books Students Read") #繪圖 pyplot.show() drawBar(books)
輸出結果:
餅形圖。餅形圖事宜扇形的面積來指代某類型的頻率,使用Matplotlib對圖書借閱量這一定性變量繪制餅形圖的代碼如下:
#繪制餅形圖 def drawPie(books): labels=['A','B','C','D','E'] bookGroup={} for book in books: bookGroup[book]=bookGroup.get(book,0)+1 #創建餅形圖 #第一個參數是扇形的面積 #labels參數為扇形的說明文字 #autopct參數為扇形占比的顯示格式 pyplot.pie([bookGroup.get(label,0) for label in labels],labels=labels,autopct='%1.1f%%') pyplot.title("Number of Books Students Read") pyplot.show() drawPie(books)
輸出結果:
(2)定量分析
直方圖類似於柱狀圖,是用柱的高度來指代頻數,不同的是其將定量數據划分為若干連續的區間,在這些連續的區間上繪制柱。
直方圖。使用Matplotlib對身高這一定量變量繪制直方圖的代碼如下:
#繪制直方圖 def drawHist(heights): #創建直方圖 #第一個參數為待繪制的定量數據,不同於定性數據,這里並沒有實現進行頻數統計 #第二個參數為划分的區間個數 pyplot.hist(heights,100) pyplot.xlabel('Heights') pyplot.ylabel('Frequency') pyplot.title('Height of Students') pyplot.show() drawHist(heights)
輸出結果:
累積曲線。使用Matplotlib對身高這一定量變量繪制累積曲線的代碼如下:
#繪制累積曲線 def drawCumulativaHist(heights): #創建累積曲線 #第一個參數為待繪制的定量數據 #第二個參數為划分的區間個數 #normal參數為是否無量綱化 #histtype參數為‘step’,繪制階梯狀的曲線 #cumulative參數為是否累積 pyplot.hist(heights,20,normed=True,histtype='step',cumulative=True) pyplot.xlabel('Heights') pyplot.ylabel('Frequency') pyplot.title('Heights of Students') pyplot.show() drawCumulativaHist(heights)
輸出結果:
3)關系分析
散點圖。在散點圖中,分別以自變量和因變量作為橫坐標。當自變量與因變量線性相關時,散點圖中的點近似分布在一條直線上。我們以身高作為自變量,體重作為因變量,討論身高對體重的影響。使用Matplotlib繪制散點圖的代碼如下:
#繪制散點圖 def drawScatter(heights,weights): #創建散點圖 #第一個參數為點的橫坐標 #第二個參數為點的縱坐標 pyplot.scatter(heights,weights) pyplot.xlabel('Heights') pyplot.ylabel('Weight') pyplot.title('Heights & Weight of Students') pyplot.show() drawScatter(heights,weights)
輸出結果:
4)探索分析
箱型圖。在不明確數據分析的目標時,我們對數據進行一些探索性的分析,可以知道數據的中心位置、發散程度及偏差程度。使用Matplotlib繪制關於身高的箱型圖代碼如下:
#繪制箱型圖 def drawBox(heights): #創建箱型圖 #第一個參數為待繪制的定量數據 #第二個參數為數據的文字說明 pyplot.boxplot([heights],labels=['Heights']) pyplot.title('Heights of Students') pyplot.show() drawBox(heights)
輸出結果:
注:
- 上四分位數與下四分位數的差叫四分位差,它是衡量數據發散程度的指標之一
- 上界線和下界線是距離中位數1.5倍四分位差的線,高於上界線或者低於下界線的數據為異常值
描述性統計是容易操作、直觀簡潔的數據分析手段。但是由於簡單,對於多元變量的關系難以描述。現實生活中,自變量通常是多元的:決定體重的不僅有身高,還有飲食習慣、肥胖基因等因素。通過一些高級的數據處理手段,我們可以對多元變量進行處理,例如,特征工程中,可以使用互信息方法來選擇多個對因變量有較強相關性的自變量作為特征,還可以使用主成分分析法來消除一些冗余的自變量來降低運算復雜度。
參考書目:《數據館員的Python簡明手冊》