學機器學習,不會數據分析怎麽行——數據可視化分析(matplotlib)
前言
前面兩篇文章介紹了 python 中兩大模塊 pandas 和 numpy 的一些基本使用方法,然而,僅僅會處理數據還是不夠的,我們需要學會怎麽分析,毫無疑問,利用圖表對數據進行分析是最容易的,通過圖表可以很好地理解數據之間的關聯性以及某些數據的變化趨勢。因此,將在這篇博客中介紹 python 中可視化工具 matplotlib 的使用。
Figure 和 Subplot
matplotlib 的圖像都位於 Figure 對象中,可以用 plt.figure
創建一個新的 Figure
fig = plt.figure()
plt.figure
有一些選項,如 figsize(用於設置圖片大小)。不能通過空 Figure 繪圖,必須用 add_subplot
ax1 = fig.add_subplot(2,2,1) # 2*2 的圖像,選中的是4個subplot中的第一個
ax2 = fig.add_subplot(2,2,2)
ax3 = fig.add_subplot(2,2,3)
最終得到的圖如下所示
畫三張圖
ax3.plot(np.random.randn(50).cumsum(),‘k--‘) # k--表示線型 _ = ax1.hist(np.random.randn(100),bins=20,color=‘k‘,alpha=0.3) ax2.scatter(np.arange(30),np.arange(30)+3*np.random.randn(30))
上圖中只是三種圖表類型,你可以在matplotlib的文檔中找到各種圖表類型。由於根據特定布局創建Figure和subplot是一件非常常見的任務,於是便出現了一個更為方便的方法 plt.subplots
,它可以創建一個新的Figure,並返回一個含有已創建的subplot對象的NumPy數組
fig, axes = plt.subplots(2,3)
axes
這種方法非常的實用,我們可以輕松對axes數據進行索引。我們還可以通過 sharex
和 sharey
指定 subplot 應該具有的X軸和Y軸。在比較相同範圍的數據時,這也是非常實用的,否則,matplotlib 會自動縮放各圖表的界限。
圖表各要素
下面在介紹介紹如何添加圖表的各個要素
標題、軸標簽、刻度以及刻度標簽
要修改X軸的刻度,最簡單的方法是使用set_xticks和set_xticklabels。前者告訴matplotlib要將刻度放在數據範圍中的哪些位置,默認情況下,這些位置也就是刻度標簽。但我們可以通過set_xticklabels將任何其他的值作用於標簽
# 繪制一段隨機漫步
fig = plt.figure()
ax = fig.add_subplot(1,1,1)
ax.plot(np.random.randn(1000).cumsum())
ticks = ax.set_xticks([0,250,500,750,1000])
labels = ax.set_xticklabels([‘one‘,‘two‘,‘three‘,‘four‘,‘five‘])
ax.set_title(‘My first matplotlib plot‘)
ax.set_xlabel(‘stages‘)
圖例
ax.plot(np.random.randn(1000).cumsum(),label = ‘one‘)
ax.plot(np.random.randn(1000).cumsum(),‘k--‘,label=‘two‘)
ax.plot(np.random.randn(1000).cumsum(),‘k.‘,label=‘three‘)
ax.legend(loc=‘best‘) # loc 告訴matplotlib要將圖例放在哪
註釋
除標準的圖標對象之外,你可能還希望繪制一些自定以的註解(比如文本、箭頭或其他圖形等)
註解可以通過 text
, arrow
和annotate
等函數進行添加。text
可以將文本繪制在圖表的指定坐標 (x,y)? ,還可以加上一些自定以格式
ax.text(x,y,‘Hello World!‘, family=‘monospace‘, fontsize=10, verticalalignment="top", horizontalalignment="right")
x,y:表示坐標值上的值
string:表示說明文字
fontsize:表示字體大小
verticalalignment:垂直對齊方式 ,參數:[ ‘center’ | ‘top’ | ‘bottom’ | ‘baseline’ ]
horizontalalignment:水平對齊方式 ,參數:[ ‘center’ | ‘right’ | ‘left’ ]
x1 = np.random.normal(30, 3, 100)
x2 = np.random.normal(20, 2, 100)
plt.plot(x1, label = ‘plot‘)
plt.plot(x2, label = ‘2nd plot‘)
plt.legend(bbox_to_anchor=(0., 1.02, 1., .102), loc=2,
ncol=2, mode=‘expand‘, borderaxespad=0.)
plt.annotate(‘Important value‘, (55,20),
xycoords=‘data‘,
xytext=(5,38),
arrowprops = dict(arrowstyle = ‘->‘))
plt.show()
annotate(s=‘str‘ ,xy=(x,y) ,xytext=(l1,l2) ,..)
s 為註釋文本內容
xy 為被註釋的坐標點
xytext 為註釋文字的坐標位置
xycoords 參數如下:
- figure points points from the lower left of the figure 點在圖左下方
- figure pixels pixels from the lower left of the figure 圖左下角的像素
- figure fraction fraction of figure from lower left 左下角數字部分axes
- points points from lower left corner of axes 從左下角點的坐標axes
- pixels pixels from lower left corner of axes 從左下角的像素坐標
- axes fraction fraction of axes from lower left 左下角部分
- data use the coordinate system of the object being annotated(default) 使用的坐標系統被註釋的對象(默認)
- polar(theta,r) if not native ‘data’ coordinates t
extcoords
設置註釋文字偏移量
參數 | 坐標系 |
---|---|
‘figure points‘ | 距離圖形左下角的點數量 |
‘figure pixels‘ | 距離圖形左下角的像素數量 |
‘figure fraction‘ | 0,0 是圖形左下角,1,1 是右上角 |
‘axes points‘ | 距離軸域左下角的點數量 |
‘axes pixels‘ | 距離軸域左下角的像素數量 |
‘axes fraction‘ | 0,0 是軸域左下角,1,1 是右上角 |
‘data‘ | 使用軸域數據坐標系 |
arrowprops
#箭頭參數,參數類型為字典dict
- width the width of the arrow in points 點箭頭的寬度
- headwidth the width of the base of the arrow head in points 在點的箭頭底座的寬度
- headlength the length of the arrow head in points 點箭頭的長度
- shrink fraction of total length to ‘shrink’ from both ends 總長度為分數“縮水”從兩端
- facecolor 箭頭顏色
bbox給標題增加外框 ,常用參數如下:
- boxstyle方框外形
- facecolor(簡寫fc)背景顏色
- edgecolor(簡寫ec)邊框線條顏色
- edgewidth邊框線條大小
bbox=dict(boxstyle=‘round,pad=0.5‘, fc=‘yellow‘, ec=‘k‘,lw=1 ,alpha=0.5) #fc為facecolor,ec為edgecolor,lw為lineweight
pandas中的繪圖函數
我們平時基本都是使用pandas處理數據,所以,能夠利用pandas中內置的plot來畫圖會方便許多,下面將介紹幾種常用圖表的畫法
線型圖
Series 和 DataFrame 都有一個用於生成各類圖表的plot方法。默認情況下為線型圖
s = pd.Series(np.random.randn(10).cumsum(),index=np.arange(0,100,10))
s.plot()
該Series對象的索引會被傳給matplotlib,並用以繪制X軸。可以通過use_index=False禁用該功能。X軸的刻度和界限可以通過xticks和xlim選項進行調節,Y軸就用yticks和ylim。
DataFrame的plot方法會在一個subplot中為各列繪制一條線,並自動創建圖例
df = pd.DataFrame(np.random.randn(10,4).cumsum(0),columns=[‘A‘,‘B‘,‘C‘,‘D‘],index=np.arange(0,100,10))
df.plot()
Series.plot參數如下:
- label 用於圖例標簽
- ax 要在其上進行繪制的matplotlib subplot對象。
- style 將要傳給matplotlib的風格字符串(如‘ko--‘)
- alpha 圖表的填充不透明度(0-1)
- kind 可以是‘line‘ ‘bar‘ ‘barch‘ ‘kde‘
- logy 在Y軸上是同對數標尺
- use_index 將對象的索引用作刻度標簽
- rot 旋轉刻度標簽(0-360)
- xticks 用作X軸刻度的值
- yticks 用作Y軸刻度的值
- xlim X軸的界限
- ylim Y軸的界限
- grid 顯示軸網格線(默認打開)
專用於DataFrame的plot參數:
- subplots 將各個DataFrame列繪制到單獨的subplot中
- sharex 如果subplots=True,則共用同一個X軸,包括刻度和界限
- sharey 如果subplots=True,則共用同一個Y軸
- figsize 表示圖像大小的元組
- title 表示圖像標題的字符串
- legend 添加一個subplot圖例
- sort_columns 以字母表示順序繪制各列,默認使用當前列順序 註:有關時間序列的處理這篇博客中暫時不寫,將在後續博客中補充
柱狀圖
在生成線型圖的代碼中加上kind=‘bar‘或kind=‘barh‘即可生成柱狀圖。這時,Series和DataFrame的索引將會被用作X或Y刻度
fig, axes = plt.subplots(2,1)
data = pd.Series(np.random.rand(16),index=list(‘abcdefghijklmnop‘))
data.plot(kind=‘bar‘,ax=axes[0],color=‘k‘,alpha=0.8,figsize=(8,10))
data.plot(kind=‘barh‘,ax=axes[1],color=‘k‘,alpha=0.8,figsize=(8,10))
df = pd.DataFrame(np.random.rand(6,4),index=[‘one‘,‘two‘,‘three‘,‘four‘,‘five‘,‘six‘],columns=pd.Index([‘A‘,‘B‘,‘C‘,‘D‘],name=‘Genus‘))
df
df.plot(kind=‘bar‘)
df.plot(kind=‘barh‘,stacked=True) # 設置stacked為True生成堆疊圖
註:柱狀圖可以利用value_counts圖形化顯示Series中各值出現的頻率
df.div(df.sum(1).astype(float),axis=0).plot(kind=‘barh‘,stacked=True)
直方圖和密度圖
直方圖是一種可以對值頻率進行離散化顯示的柱狀圖,。數據點被拆分到離散的、間隔均勻的面元中,繪制的時各面元中數據點的數量。
length = pd.DataFrame({‘length‘: [10, 20,15,10,1,12,12,12,13,13,13,14,14,14,41,41,41,41,41,4,4,4,4]})
length.plot.hist()
與直方圖相關的一種圖表類型時密度圖,它是通過計算“可能會產生觀測數據的連續概率分布的估計”而產生的。一般的過程是將該分布近似為一組核(即諸如正態(高斯)分布之類的較為簡單的分布)。因此,密度圖也被稱作KDE圖,調用plot時加上kind=‘kde‘即可生成一張密度圖(標準混合正態分布)。
length.plot(kind=‘kde‘)
df4 = pd.DataFrame({‘a‘: np.random.randn(1000) + 1, ‘b‘: np.random.randn(1000), ‘c‘: np.random.randn(1000) - 1}, index=range(1,1001), columns=[‘a‘, ‘b‘, ‘c‘]) #bins=20表示數值分辨率,具體來說是將隨機數設定一個範圍,例如5.6,5.7,6.5,如果數值分辨率越低,則會將三個數分到5-7之間,如果數值分辨率越高,則會將5.6,5.7分到5-6之間,而6.5分到6-7之間;值越小表示分辨率越低,值越大表示分辨率越高;
df4.plot.hist(stacked=True, bins=20, alpha=0.5)
df4.diff().hist(color=‘k‘, alpha=0.5, bins=50) #可將DataFrame當中column分開
這兩種圖表常常會被畫在一起。直方圖以規格化形式給出(以便給出面元化密度),然後再在其上繪制核密度估計。
comp1 = np.random.normal(0,1,size=200)
comp2 = np.random.normal(10,2,size=200)
values = pd.Series(np.concatenate([comp1,comp2]))
values.hist(bins=100,alpha=0.3,color=‘k‘,normed=True)
values.plot(kind=‘kde‘)
散點圖
散點圖(scatter plot)是觀察兩個一維數據序列之間的關系的有效手段。matplotlib的scatter方法是繪制散點圖的主要方法。
df = pd.DataFrame(np.random.rand(50, 4), columns=[‘a‘, ‘b‘, ‘c‘, ‘d‘])
df.plot.scatter(x=‘a‘, y=‘b‘) # 以a列為X軸數值,b列為Y軸數值繪制散點圖
如果想將不同的散點圖信息繪制到一張圖片當中,需要利用不同的顏色和標簽進行區分
ax = df.plot.scatter(x=‘a‘, y=‘b‘, color=‘Blue‘, label=‘Group 1‘)
df.plot.scatter(x=‘c‘, y=‘d‘, color=‘Green‘, label=‘Group 2‘, ax=ax)
在探索式數據分析(EDA)工作中,同時觀察一組變量的散點圖是很有意義的,這也被稱為散點圖矩陣。
from sklearn.datasets import load_iris # 使用sklearn庫裏的iris數據集
iris_dataset = load_iris()
from sklearn.model_selection import train_test_split
X_train,X_test,y_train,y_test = train_test_split(iris_dataset[‘data‘],iris_dataset[‘target‘],random_state=0)
iris_dataframe=pd.DataFrame(X_train,columns=iris_dataset.feature_names)
grr = pd.plotting.scatter_matrix(iris_dataframe,marker=‘o‘,c = y_train,hist_kwds={‘bins‘:20},figsize=(12,10))
餅圖
餅圖展現的是百分比關系
series = pd.Series(4 * np.random.rand(4), index=[‘a‘, ‘b‘, ‘c‘, ‘d‘], name=‘series‘)
series.plot.pie(figsize=(6, 6))
對於DataFrame對象,每一個column都可獨立繪制一張餅圖,但需要利用subplots=True參數將,每個餅圖繪制到同一張圖中。 df = pd.DataFrame(3 * np.random.rand(4, 2), index=[‘a‘, ‘b‘, ‘c‘, ‘d‘], columns=[‘x‘, ‘y‘]) df.plot.pie(subplots=True, figsize=(8, 4))
箱型圖(略)
由於箱型圖接觸不多,涉及內容較多且較為重要,後面會另寫一篇關於箱型圖的博客
各種繪圖方式對於缺失值的處理
Missing values are dropped, left out, or filled depending on the plot type
圖表 | 處理方式 |
---|---|
Plot Type | NaN Handling |
Line | Leave gaps at NaNs |
Line (stacked) | Fill 0’s |
Bar | Fill 0’s |
Scatter | Drop NaNs |
Histogram | Drop NaNs (column-wise) |
Box | Drop NaNs (column-wise) |
Area | Fill 0’s |
KDE | Drop NaNs (column-wise) |
Hexbin | Drop NaNs |
Pie | Fill 0’s |
總結
上面是一些常用圖的畫法介紹,當然,我們還有很多可畫的圖如箱型圖、區域面積圖、等高線圖等等,也能利用 matplotlib 來繪制地圖,當然這些在這就暫時先不介紹了,以後需要了再一一補充。
參考
《利用python進行數據分析》第八章
https://blog.csdn.net/wangxingfan316/article/details/80033557
https://blog.csdn.net/genome_denovo/article/details/78322628
https://blog.csdn.net/Notzuonotdied/article/details/77876080
學機器學習,不會數據分析怎麽行——數據可視化分析(matplotlib)