文章目錄
一、數據可視化介紹
數據可視化是指將數據放在可視環境中、進一步理解數據的技術,可以通過它更加詳細地了解隱藏在數據表面之下的模式、趨勢和相關性。
Python提供了很多數據可視化的庫:
- matplotlib
是Python基礎的畫圖庫,官網為https://matplotlib.org/,在案例地址https://matplotlib.org/gallery/index.html中介紹了很多種類的圖和代碼示例。 - pandas
是在matplotlib的基礎上實現畫圖的,官網為https://pandas.pydata.org/。 - matlpotlib和pandas結合
利用pandas進行數據讀取、數據清洗和數據選取等操作,再使用matlpotlib顯示數據。
二、matplotlib和pandas畫圖
1.matplotlib簡介和簡單使用
matplotlib是Python最著名的繪圖庫,它提供了一整套和Matlab相似的命令API,十分適合
交互式地進行制圖;也可以方便地將它作為繪圖控件,嵌入GUI應用程序中。
文檔相當完備,並且Gallery頁面中有上百幅縮略圖,打開之后都有源代碼。如果需要繪制某種類型的圖,只需要在這個頁面中進行簡單的瀏覽、復制、粘貼,就能實現畫圖。
https://matplotlib.org/gallery.html中有大量的縮略圖案例可以使用。
matplotlib畫圖的子庫:
- pyplot子庫
提供了和matlab類似的繪圖API,方便用戶快速繪制2D圖表。 - pylab模塊
其中包括了許多numpy和pyplot中常用的函數,方便用戶快速進行計算和繪圖,可以用於IPython中的快速交互式使用。
使用matplotlib快速繪圖導入庫和創建繪圖對象如下:
import matplotlib.pyplot as plt plt.figure(figsize=(8,4))
- 1
- 2
- 3
創建繪圖對象時,同時使它成為當前的繪圖對象。
通過figsize參數可以指定繪圖對象的寬度和高度,單位為英寸;
dpi參數指定繪圖對象的分辨率,即每英寸多少個像素,缺省值為80。
因此本例中所創建的圖表窗口的寬度為8 * 80 = 640
像素。
也可以不創建繪圖對象直接調用plot方法繪圖,matplotlib會自動創建一個繪圖對象。
如果需要同時繪制多幅圖表的話,可以給figure傳遞一個整數參數指定圖標的序號,如果所指定序號的繪圖對象已經存在的話,將不創建新的對象,而只是讓它成為當前繪圖對象。
pyplot畫圖簡單使用如下:
import numpy as np import matplotlib.pyplot as plt # 首先載入matplotlib的繪圖模塊pyplot,並且重命名為plt x = np.linspace(0, 10, 1000) y = np.sin(x) z = np.cos(x**2) plt.figure(figsize=(8,4)) #2 創建繪圖對象 plt.plot(x,y,label="$sin(x)$",color="red",linewidth=2) plt.plot(x,z,"b--",label="$cos(x^2)$") plt.xlabel("Time(s)") plt.ylabel("Volt") plt.title("PyPlot First Example") plt.ylim(-1.2,1.2) plt.legend() plt.show()
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
顯示:
其中:
plt.plot(x,y,label="$sin(x)$",color="red",linewidth=2) plt.plot(x,z,"b--",label="$cos(x^2)$")
- 1
- 2
第一行將x、y數組傳遞給plot之后,用關鍵字參數指定各種屬性:
- label
給所繪制的曲線取一個名字,用於在圖示(legend)中顯示;
在字符串前后添加$
符號,就會使用內置的latex引擎繪制數學公式。 - color
指定曲線的顏色:顏色可以用英文單詞,或者以#
字符開頭的三個16進制數,例如#ff0000
表示紅色,或者用值在0到1范圍之內的三個元素的元組表示,例如(1.0, 0.0, 0.0)
也表示紅色。 - linewidth
指定曲線的寬度,可以不是整數,也可以使用縮寫形式的參數名lw
。 - 曲線樣式
第三個參數b--
指定曲線的顏色和線型,它通過一些易記的符號指定曲線的樣式,其中b表示藍色,–表示線型為虛線。
在IPython中輸入plt.plot?
可以查看格式化字符串以及各個參數的詳細說明。
plt.xlabel("Time(s)") plt.ylabel("Volt") plt.title("PyPlot First Example") plt.ylim(-1.2,1.2) plt.legend()
- 1
- 2
- 3
- 4
- 5
通過一系列函數設置當前Axes對象的各個屬性:
- xlabel、ylabel
分別設置X、Y軸的標題文字。 - title
設置子圖的標題。 - xlim、ylim
分別設置X、Y軸的顯示范圍。 - legend
顯示圖示,即圖中表示每條曲線的標簽(label)和樣式的矩形區域。
最后調用plt.show()
顯示出繪圖窗口。
一個繪圖對象(figure)可以包含多個軸(axis),在Matplotlib中用軸表示一個繪圖區域,可以將其理解為子圖。上面的第一個例子中,繪圖對象只包括一個軸,因此只顯示了一個軸(子圖Axes)。可以使用subplot
函數快速繪制有多個軸的圖表。
subplot函數的調用形式如下:
subplot(numRows, numCols, plotNum)
- 1
subplot將整個繪圖區域等分為numRows行和numCols列個子區域,然后按照從左到右、從上到下的順序對每個子區域進行編號,左上的子區域的編號為1。
如果numRows、numCols和plotNum這三個數都小於10的話,可以把它們縮寫為一個整數,例如subplot(323)
和subplot(3,2,3)
是相同的。
subplot在plotNum指定的區域中創建一個軸對象,如果新創建的軸和之前創建的軸重疊,之前的軸將被刪除。
如下:
for idx, color in enumerate("rgbyck"): plt.subplot(320+idx+1, facecolor=color) plt.show()
- 1
- 2
- 3
顯示:
可以看到:
創建3行2列共6個軸,通過facecolor
參數給每個軸設置不同的背景顏色。
如果希望某個軸占據整個行或者列的話,可以如下:
plt.subplot(221) # 第一行的左圖 plt.subplot(222) # 第一行的右圖 plt.subplot(212) # 第二整行 plt.show()
- 1
- 2
- 3
- 4
顯示:
再舉一個創建子圖的例子:
plt.figure(1) # 創建圖表1 plt.figure(2) # 創建圖表2 ax1 = plt.subplot(211) # 在圖表2中創建子圖1 ax2 = plt.subplot(212) # 在圖表2中創建子圖2 x = np.linspace(0, 3, 100) for i in range(5): plt.figure(1) # 選擇圖表1 plt.plot(x, np.exp(i*x/3)) plt.sca(ax1) # 選擇圖表2的子圖1 Set the current Axes instance to ax. plt.plot(x, np.sin(i*x)) plt.sca(ax2) # 選擇圖表2的子圖2 plt.plot(x, np.cos(i*x)) plt.show()
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
顯示:
首先通過figure()
創建了兩個圖表,它們的序號分別為1和2;
然后在圖表2中創建了上下並排的兩個子圖,並用變量ax1和ax2保存。
在循環中:
先調用figure(1)
讓圖表1成為當前圖表,並在其中繪圖。
然后調用sca(ax1)
和sca(ax2)
分別讓子圖ax1和ax2成為當前子圖,並在其中繪圖。
當它們成為當前子圖時,包含它們的圖表2也自動成為當前圖表,因此不需要調用figure(2)
依次在圖表1和圖表2的兩個子圖之間切換,逐步在其中添加新的曲線即可。
其中,twinx()
可以為圖增加縱坐標軸,使用如下:
x = np.arange(1, 21, 0.1) y1 = x * x y2 = np.log(x) plt.plot(x, y1) # 添加一條y軸的坐標軸 plt.twinx() plt.plot(x, y2) plt.show()
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
顯示:
進一步使用如下:
import numpy as np import matplotlib.pyplot as plt x = np.arange(1, 20, 1) y1 = x * x y2 = np.log(x) fig = plt.figure() ax1 = fig.add_subplot(111) ax1.plot(x, y1, label = "$y1 = x * x$", color = "r") ax1.legend(loc = 0) # 設置對應坐標軸的名稱 ax1.set_ylabel("y1") ax1.set_xlabel("Compare y1 and y2") # 設置x軸刻度的數量 ax = plt.gca() ax.locator_params("x", nbins = 20) # 添加坐標軸,並在新添加的坐標軸中畫y2 = log(x)圖像 ax2 = plt.twinx() ax2.set_ylabel("y2") ax2.plot(x, y2, label = "$y2 = log(x)$") ax2.legend(loc = 0) plt.show()
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
顯示:
2.matplotlib常見作圖類型
畫圖在工作中在所難免,尤其在進行數據探索時顯得尤其重要,matplotlib常見的一些作圖種類如下:
- 散點圖
- 條形圖
- 餅圖
- 三維圖
先導入庫和基礎配置如下:
from __future__ import division from numpy.random import randn import numpy as np import os import matplotlib.pyplot as plt np.random.seed(12345) plt.rc('figure', figsize=(10, 6)) from pandas import Series, DataFrame import pandas as pd np.set_printoptions(precision=4) get_ipython().magic(u'matplotlib inline') get_ipython().magic(u'pwd')
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
打印:
'XXX\\3_Visualization_Of_Data_Analysis\\basicuse'
- 1
基礎畫圖如下:
# matplotlib創建圖表 plt.plot([1,2,3,2,3,2,2,1]) plt.show() plt.plot([4,3,2,1],[1,2,3,4]) plt.show()
- 1
- 2
- 3
- 4
- 5
- 6
顯示:
畫三角函數曲線如下:
# 畫簡單的圖形 from pylab import * x=np.linspace(-np.pi,np.pi,256,endpoint=True) c,s=np.cos(x),np.sin(x) plot(x,c, color="blue", linewidth=2.5, linestyle="-", label="cosine") plot(x,s,color="red", linewidth=2.5, linestyle="-", label="sine") show()
- 1
- 2
- 3
- 4
- 5
- 6
- 7
顯示:
畫散點圖如下:
# 散點圖 from pylab import * n = 1024 X = np.random.normal(0,1,n) Y = np.random.normal(0,1,n) scatter(X,Y) show()
- 1
- 2
- 3
- 4
- 5
- 6
- 7
顯示:
畫條形圖如下:
#條形圖 from pylab import * n = 12 X = np.arange(n) Y1 = (1-X/float(n)) * np.random.uniform(0.5,1.0,n) Y2 = (1-X/float(n)) * np.random.uniform(0.5,1.0,n) bar(X, +Y1, facecolor='#9999ff', edgecolor='white') bar(X, -Y2, facecolor='#ff9999', edgecolor='white') for x,y in zip(X,Y1): text(x+0.4, y+0.05, '%.2f' % y, ha='center', va= 'bottom') ylim(-1.25,+1.25) show()
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
顯示:
餅圖如下:
#餅圖 from pylab import * n = 20 Z = np.random.uniform(0,1,n) pie(Z) show()
- 1
- 2
- 3
- 4
- 5
- 6
顯示:
畫立體圖如下:
#畫三維圖 import numpy as np from mpl_toolkits.mplot3d import Axes3D from pylab import * fig=figure() ax=Axes3D(fig) x=np.arange(-4,4,0.1) y=np.arange(-4,4,0.1) x,y=np.meshgrid(x,y) R=np.sqrt(x**2+y**2) z=np.sin(R) ax.plot_surface(x,y,z,rstride=1,cstride=1,cmap='hot') show()
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
顯示:
畫其他簡單圖形如下:
#更多簡單的圖形 x = [1,2,3,4] y = [5,4,3,2] plt.figure() plt.subplot(2,3,1) plt.plot(x, y) plt.subplot(232) plt.bar(x, y) plt.subplot(233) plt.barh(x, y) plt.subplot(234) plt.bar(x, y) y1 = [7,8,5,3] plt.bar(x, y1, bottom=y, color = 'r') plt.subplot(235) plt.boxplot(x) plt.subplot(236) plt.scatter(x,y) plt.show()
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
顯示:
3.使用pandas畫圖
pandas中畫圖的主要類型包括:
- 累和圖
- 柱狀圖
- 散點圖
- 餅圖
- 矩陣散點圖
先導入所需要的庫:
from __future__ import division from numpy.random import randn import numpy as np import os import matplotlib.pyplot as plt np.random.seed(12345) from pandas import Series, DataFrame import pandas as pd %matplotlib inline
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
在pandas中,有行標簽、列標簽和分組信息等,如果使用matplotlib畫圖,可能需要一大堆的代碼,現在調用Pandas的plot()
方法即可簡單實現。
畫簡單線圖如下:
#線圖 s = Series(np.random.randn(10).cumsum(), index=np.arange(0, 100, 10)) s.plot() plt.show()
- 1
- 2
- 3
- 4
顯示:
pandas.Series.plot()
的常見參數及說明如下:
參數 | 說明 |
---|---|
參數 | 說明 |
label | 用於圖例的標簽 |
ax | 要在其上進行繪制的matplotlib subplot對象,如果沒有設置,則使用當前matplotlib subplot |
style | 將要傳給matplotlib的風格字符串,例如'ko-' |
alpha | 圖表的填充不透明(0-1) |
kind | 可以是'line' 、'bar' 、'barh' 、'kde' |
logy | 在Y軸上使用對數標尺 |
use_index | 將對象的索引用作刻度標簽 |
rot | 旋轉刻度標簽(0-360) |
xticks | 用作X軸刻度的值 |
yticks | 用作Y軸刻度的值 |
xlim | X軸的界限 |
ylim | Y軸的界限 |
grid | 顯示軸網格線 |
Pandas的大部分繪圖方法都有一個可選的ax參數,它可以是一個matplotlib的subplot對象,從而能夠在網絡布局中更為靈活地處理subplot的位置。DataFrame的plot方法會在一個subplot中為各列繪制一條線,並自動創建圖例。
畫多列線圖如下:
df = DataFrame(np.random.randn(10, 4).cumsum(0), columns=['A', 'B', 'C', 'D'], index=np.arange(0, 100, 10)) df.plot() plt.show()
- 1
- 2
- 3
- 4
- 5
顯示:
相對於Series,DataFrame還有一些用於對列進行靈活處理的選項,例如要將所有列都繪制到一個subplot中還是創建各自的subplot等,具體如下:
參數 | 說明 |
---|---|
subplots | 將各個DataFrame列繪制到單獨的subplot中 |
sharex | 如果subplots=True,則共用同一個X軸,包括刻度和界限 |
sharey | 如果subplots=True,則共用同一個Y軸,包括刻度和界限 |
figsize | 表示圖像大小的元組 |
title | 表示圖像標題的字符串 |
legend | 添加—個subplot圖例(默認為True) |
sort_columns | 以字母表順序繪制各列,默認使用前列順序 |
畫簡單累和圖如下:
#線圖 CUM plt.close('all') s = Series(np.random.randn(10).cumsum(), index=np.arange(0, 100, 10)) s.plot() plt.show()
- 1
- 2
- 3
- 4
- 5
- 6
顯示:
畫多列的類和圖如下:
df = DataFrame(np.random.randn(10, 4).cumsum(0), columns=['A', 'B', 'C', 'D'], index=np.arange(0, 100, 10)) df.plot() plt.show()
- 1
- 2
- 3
- 4
- 5
顯示:
當提升了數據規模之后,累和圖如下:
s = pd.Series([2, np.nan, 5, -1, 0]) print(s) print(s.cumsum()) #畫累和圖 ts=pd.Series(np.random.randn(1000),index=pd.date_range('1/1/2000',periods=1000)) ts=ts.cumsum() ts.plot() plt.show() df=pd.DataFrame(np.random.randn(1000,4),index=ts.index,columns=list('ABCD')) # cumulative意為累計、累積,這個函數可以返回一個累計值,經常會遇到月累計、年累計這種指標,會用這個函數 df=df.cumsum() df.plot() plt.show()