學會Python-Matplotlib可視化,快速進行數據分析(1)——一文詳解常見統計圖的繪制
matplotlib庫
Matplotlib是Python的繪圖庫,它提供了一整套和 matlab 相似的命令 API,可以生成出版質量級別的精美圖形,Matplotlib使繪圖變得非常簡單,在易用性和性能間取得了優異的平衡。
曲線圖
曲線圖的繪制
作為繪圖程序的Hello World,我們將首先繪制一條簡單的曲線。同時還將簡單介紹matplotlib的工作原理。
# plot.py
import matplotlib.pyplot as plt
x = range(50)
y = [value * 2 for value in x]
plt.plot(x, y)
plt.show()
上述代碼將會繪制曲線y=2*x,其中x在[0,50]范圍內,如下所示:
可以看到窗口上方還包含多個圖標,其中:
項目 | Value |
---|---|
![]() |
此按鈕用於將所繪制的圖形另存為所需格式的圖片,包括png,jpg,pdf,svg等常見格式 |
![]() |
此按鈕用於調整圖片的尺寸,邊距等圖片屬性 |
![]() |
此按鈕用於縮放圖片,用於觀察圖形細節,單擊此按鈕后,在圖形上使用鼠標左鍵拖拽進行放大,使用鼠標右鍵拖拽進行縮小 |
![]() |
此按鈕用於移動圖形,可以與“縮放”按鈕結合觀察放大后圖片的具體細節,同時,單擊此按鈕后,在圖形上使用鼠標右鍵拖拽可以縮放坐標軸的比例 |
![]() |
此按鈕用於將圖形恢復到其初始狀態,取消縮放、移動等操作 |
Tips:plt.plot(x, y)用於繪制一條曲線,其中,曲線點的x坐標在列表x中給出,曲線點的y坐標在列表y中給出。
由於matplotlib它只專注於繪圖,因此如果想從文件中讀取輸入或進行一些中間計算,那么必須使用Python模塊,但不用擔心,matplotlib與其他模塊具有良好的兼容性,並不涉及過多的技巧。例如,要生成大量統計圖形,可能需要使用科學計算包,如Numpy和Python的文件讀取I/O模塊。在接下來的講解中會給出相應的示例。
結合Numpy庫,繪制曲線圖
繪制曲線cos(x),x在[0, 2*pi]區間內:
# cos_1.py
import math
import matplotlib.pyplot as plt
scale = range(100)
x = [(2 * math.pi * i) / len(scale) for i in scale]
y = [math.cos(i) for i in x]
plt.plot(x, y)
plt.show()
若采用Numpy庫,則可以使用以下等效代碼:
# cos_2.py
import numpy as np
import matplotlib.pyplot as plt
x = np.linspace(0, 2 * np.pi, 100)
y = np.cos(x)
plt.plot(x, y)
plt.show()
所繪制圖形如下所示:
Tips:雖然Numpy對於可視化而言並非必要,但可以看出使用Numpy庫可以更加高效。
Numpy可以一次對整個數組執行操作,可以使代碼更高效,以繪制[-10,10]區間內的曲線 y = x 3 + 5 x − 10 y=x^3+5x-10 y=x3+5x−10為例:
# plot_np.py
import numpy as np
import matplotlib.pyplot as plt
x = np.linspace(-10, 10, 800)
y = x ** 3 + 5 * x - 10
plt.plot(x, y)
plt.show()
繪制圖形如下
繪制多曲線圖
很多時候我們需要對比多組數據,以發現數據間的異同,此時就需要在一張圖片上繪制多條曲線——多曲線圖,下圖展示了在同一圖片中繪制函數 y = x y=x y=x、 y = x 2 y=x^2 y=x2, y = l o g e x y=log_ex y=logex以及 y = s i n ( x ) y=sin(x) y=sin(x):
# plot_multi_curve.py
import numpy as np
import matplotlib.pyplot as plt
x = np.linspace(0.1, 2 * np.pi, 100)
y_1 = x
y_2 = np.square(x)
y_3 = np.log(x)
y_4 = np.sin(x)
plt.plot(x,y_1)
plt.plot(x,y_2)
plt.plot(x,y_3)
plt.plot(x,y_4)
plt.show()
上述腳本繪制圖形如下:
Tips:一條曲線的繪制需要調用一次plt.plot(),而plt.show()只需調用一次。這種延遲呈現機制是matplotlib的核心,我們可以聲明在任何時間繪制圖形,但只有在調用plt.show()時才會渲染顯示圖形。
為了更好的說明這種延遲呈現機制,編寫以下代碼:
# deferred_rendering.py
import numpy as np
import matplotlib.pyplot as plt
def plot_func(x, y):
x_s = x[1:] - y[:-1]
y_s = y[1:] - x[:-1]
plt.plot(x[1:], x_s / y_s)
x = np.linspace(-5, 5, 200)
y = np.exp(-x ** 2)
plt.plot(x, y)
plot_func(x, y)
plt.show()
繪制圖形如下:
可以看到,盡管其中一個plt.plot()是在plot_func函數中調用的,它對圖形的呈現沒有任何影響,因為plt.plot()只是聲明了我們要呈現的內容,但還沒有執行渲染。因此可以使用此特性結合for循環、條件判斷等語法完成復雜圖形的繪制,同時也可以在同一張圖中組合不同類型的統計圖。
讀取數據文件繪制曲線圖
很多情況下數據都是存儲於文件中,因此,需要首先讀取文件中的數據,再進行繪制,說明起見,以.txt
文件為例,其他諸如Excel、CSV文件
可以使用pandas、numpy
等庫進行讀取。
假設存在data.txt
文件如下:
0 1
1 2
2 5
4 17
5 26
6 37
讀取數據和繪制的代碼如下:
# read_txt.py
import matplotlib.pyplot as plt
x, y = [], []
for line in open('data.txt', 'r'):
values = [float(s) for s in line.split()]
x.append(values[0])
y.append(values[1])
plt.plot(x, y)
plt.show()
如果使用Numpy庫,其等效代碼可以寫為:
import matplotlib.pyplot as plt
import numpy as np
data = np.loadtxt('data.txt')
plt.plot(data[:,0], data[:,1])
plt.show()
散點圖
當繪制曲線圖時,我們假設點與點之間存在序列關系。而散點圖是簡單地繪制點,它們之間並不存在連接。
import numpy as np
import matplotlib.pyplot as plt
data = np.random.rand(1000, 2)
plt.scatter(data[:,0], data[:,1])
plt.show()
Tips:函數plt.scatter()的調用方式與plt.plot()完全相同,分別將點的x和y坐標作為輸入參數。
條形圖
條形圖具有豐富的表現形式,常見的類型包括單組條形圖,多組條形圖,堆積條形圖和對稱條形圖等。
單組條形圖
條形圖的每種表現形式都可以繪制成垂直條形圖或水平條形圖,以單組條形圖的兩種繪制方式為例。
垂直條形圖
import matplotlib.pyplot as plt
data = [10., 20., 5., 15.]
plt.bar(range(len(data)), data)
plt.show()
Tips:plt.plot()函數的作用是:接收兩個參數,包括每個條形的x坐標和每個條行的高度。
通過可選參數width
,pyplot.bar()提供了一種控制條形圖中條狀寬度的方法:
import matplotlib.pyplot as plt
data = [10., 20., 5., 15.]
plt.bar(range(len(data)), data, width=0.5)
plt.show()
水平條形圖
如果更喜歡水平條形外觀,就可以使用plt.barh()
函數,在用法方面與plt.bar()
基本相同,但是修改條形寬度(或者在水平條形圖中應該稱為高度)的參數需要使用height
:
import matplotlib.pyplot as plt
data = [10., 20., 5., 15.]
plt.barh(range(len(data)), data, height=0.5)
plt.show()
多組條形圖
當需要比較不同年份相應季度的銷量等此類需求時,我們可能需要多組條形圖。
import numpy as np
import matplotlib.pyplot as plt
data = [[10., 20., 30., 20.],[40., 25., 53., 18.],[6., 22., 52., 19.]]
x = np.arange(4)
plt.bar(x + 0.00, data[0], color = 'b', width = 0.25)
plt.bar(x + 0.25, data[1], color = 'g', width = 0.25)
plt.bar(x + 0.50, data[2], color = 'r', width = 0.25)
plt.show()
堆積條形圖
通過使用plt.bar()
函數中的可選參數,可以繪制堆積條形圖。
import matplotlib.pyplot as plt
y_1 = [3., 25., 45., 22.]
y_2 = [6., 25., 50., 25.]
x = range(4)
plt.bar(x, y_1, color = 'b')
plt.bar(x, y_2, color = 'r', bottom = y_1)
plt.show()
Tips:plt.bar()函數的可選參數bottom允許指定條形圖的起始值。
可以結合for循環,利用延遲呈現機制堆疊更多的條形:
import numpy as np
import matplotlib.pyplot as plt
data = np.array([[5., 30., 45., 22.], [5., 25., 50., 20.], [1., 2., 1., 1.]])
x = np.arange(data.shape[1])
for i in range(data.shape[0]):
plt.bar(x, data[i], bottom = np.sum(data[:i], axis = 0))
plt.show()
對稱條形圖
一個簡單且有用的技巧是對稱繪制兩個條形圖。例如想要繪制不同年齡段的男性與女性數量的對比:
import numpy as np
import matplotlib.pyplot as plt
w_pop = np.array([5., 30., 45., 22.])
m_pop = np.array( [5., 25., 50., 20.])
x = np.arange(4)
plt.barh(x, w_pop)
plt.barh(x, -m_pop)
plt.show()
圖中女性人口的條形圖照常繪制。然而,男性人口的條形圖的條形圖的條形圖向左延伸,而不是向右延伸。可以使用數據的負值來快速實現對稱條形圖的繪制。
餅圖
餅圖可以用於對比數量間的相對關系:
import matplotlib.pyplot as plt
data = [10, 15, 30, 20]
plt.pie(data)
plt.show()
Tips:plt.pie()函數將一系列值作為輸入,將值傳遞給matplolib,它就會自動計算各個值在餅圖中的相對面積,並進行繪制。
直方圖
直方圖是概率分布的圖形表示。事實上,直方圖只是一種特殊的條形圖。我們可以很容易地使用matplotlib的條形圖函數,並進行一些統計運算來生成直方圖。但是,直方圖非常有用,因此matplotlib提供了一個更加方便的函數:
import numpy as np
import matplotlib.pyplot as plt
x = np.random.randn(1024)
plt.hist(x, bins = 20)
plt.show()
Tips:plt.hist()函數的作用是:獲取一系列值作為輸入。值的范圍將被划分為大小相等的范圍(默認情況下數量為10),然后生成條形圖,一個范圍對應一個條柱,一個條柱的高度是相應范圍內中的值的數量,條柱的數量由可選參數bins確定。
箱形圖
箱形圖可以通過方便地顯示一組值的中位數、四分位數、最大值和最小值來比較值的分布。
import numpy as np
import matplotlib.pyplot as plt
data = np.random.randn(200)
plt.boxplot(data)
plt.show()
Tips:plt.boxplot()函數的作用是:獲取一組值,並自動計算平均值、中位數和其他統計量。
箱形圖描述:
- 圖中黃線是分布的中位數。
- 方形箱框包括從下四分位數Q1到上四分位數Q3的50%的數據。
- 下盒須的下四分位延伸到1.5(Q3-Q1)。
- 上盒須從上四分位延伸至1.5 (Q3-Q1)。
- 離盒須較遠的數值用圓圈標記。
要在單個圖形中繪制多個箱形圖,對每個箱形圖調用一次plt.boxplot()
是不可行。它會將所有箱形圖畫在一起,形成一個混亂的、不可讀的圖形。如果想要到達符合要求的效果,只需在一次調用plt.boxplot()
中,同時繪制多個箱形圖即可,如下所示:
import numpy as np
import matplotlib.pyplot as plt
data = np.random.randn(200, 6)
plt.boxplot(data)
plt.show()
三角網格圖
處理空間位置時會出現網格圖。除了顯示點之間的距離和鄰域關系外,三角網格圖也是表示地圖的一種方便方法。
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.tri as tri
data = np.random.rand(200, 2)
triangles = tri.Triangulation(data[:,0], data[:,1])
plt.triplot(triangles)
plt.show()
Tips:代碼中導入了matplotlib.tri模塊,該模塊提供了從點計算三角網格的輔助函數。
系列鏈接
學會Python-Matplotlib可視化,快速完成數據分析(2)——自定義顏色繪制精美統計圖
學會Python-Matplotlib可視化,快速完成數據分析(3)——自定義樣式繪制精美統計圖
學會Python-Matplotlib可視化,快速完成數據分析(4)——添加注釋讓統計圖通俗易懂