Matplotlib 繪圖教程(2D進階)


一、實驗介紹

1.1 實驗內容

Matplotlib 是支持 Python 語言的開源繪圖庫,因爲其支持豐富的繪圖類型、簡單的繪圖方式以及完善的接口文檔,深受 Python 工程師、科研學者、數據工程師等各類人士的喜歡。這是 Matplotlib 繪圖課程的第 2 章節,將帶你學會如何使用參數繪出更復雜的 2D 圖像。

1.2 實驗知識點

  • Matplotlib 繪製 2D 圖像

1.3 實驗環境

  • python2.7
  • Xfce 終端
  • ipython 終端

1.4 適合人羣

本課程難度爲一般,屬於初級級別課程,適合具有 Python 基礎,並對使用 Matplotlib 繪圖感興趣的用戶。

二、二維繪圖進階

在前一個章節中,我們已經瞭解到瞭如何使用 Matplotlib 繪出常用的圖像,包括線型圖、餅狀圖、散點圖等。但是,Matplotlib 默認的樣式的確算不上美觀。所以,這一個章節就是如何設置繪圖方法的參數,從而畫出更漂亮和自己想要的圖形。

2.1 線型圖樣式

我們已經知道了,線型圖通過 matplotlib.pyplot.plot(*args, **kwargs) 方法繪出。其中,args 代表數據輸入,而 kwargs 的部分就是用於設置樣式參數了。

二維線型圖包含的參數超過 40 餘項(文檔 P1390)。其中常用的也有 10 餘項,選取一些比較有代表性的參數列舉如下:

參數 含義
alpha= 設置線型的透明度,從 0.0 到 1.0
color= 設置線型的顏色
fillstyle= 設置線型的填充樣式
linestyle= 設置線型的樣式
linewidth= 設置線型的寬度
marker= 設置標記點的樣式
…… ……

對於上面提到的這幾項。

線型顏色 color = 的預設值(文檔 P1527)有:

color =參數值 顏色
b 藍色
g 綠色
r 紅色
w 白色
m 洋紅色
y 黃色
k 黑色
…… ……

其實,大部分都是所顏色所對應的英文名稱首字母。當然,你也可以通過color = '#008000'的方式來設置任何你想要的顏色。

線型的樣式 linestyle = 預設的參數值(文檔 P1250)有:

linestyle =參數值 線型
'-' 默認實線
'--' 虛線
'-.' 間斷線
':' 點狀線

下圖展示了 4 種常見線型的樣式

此處輸入圖片的描述

樣本點標記樣式 marker = 預設的參數值(文檔 P1527)就更多了:

marker =參數值 樣本點標記
'.' 實心點
',' 像素點
'o' 空心點
'p' 五角形
'x' x 形
'+' + 形
…… ……

下圖展示了所有標記對應的參數值和樣式

此處輸入圖片的描述

下面,我們來重新畫一遍正弦函數的圖像。添加幾個參數,希望它不再那麼單調。由於在線環境的 Matplotlib 版本較低,在本地環境運行的最新版本畫出來的默認圖像樣式會更好看一些。

# -*- coding: utf-8 -*

from matplotlib import pyplot as plt  # 載入 pyplot 繪圖模塊
import numpy as np  # 載入數值計算模塊

# 在 -2PI 和 2PI 之間等間距生成 1000 個值,也就是 X 座標
X = np.linspace(-2 * np.pi, 2 * np.pi, 1000)
# 計算 sin() 對應的縱座標
y1 = np.sin(X)
# 計算 cos() 對應的縱座標
y2 = np.cos(X)

# 向方法中 `*args` 輸入 X,y 座標
plt.plot(X, y1, color='r', linestyle='--', linewidth=2, alpha=0.8)
plt.plot(X, y2, color='b', linestyle='-', linewidth=2)
plt.show()

此處輸入圖片的描述

2.2 散點圖樣式

除了線型圖以外,散點圖也是常用圖形之一。例如,我們在使用機器學習算法聚類的時候,往往就會通過散點圖將樣本數據展示出來。

Matplotlib 中,繪製散點圖的方法我們已經知道了,那就是 matplotlib.pyplot.scatter()。接下來,我們就看一看它包含有哪些參數。

參數 含義
s= 散點大小
c= 散點顏色
marker= 散點樣式
cmap= 定義多類別散點的顏色
alpha= 點的透明度
edgecolors= 散點邊緣顏色

其中,散點的大小通過設置數值大小控制。散點的顏色可以是一種,參數值和線型的顏色設置類似。散點的顏色也可以是多種,可以使用一個列表對每一個點的顏色單獨設置。

# -*- coding: utf-8 -*

from matplotlib import pyplot as plt  # 載入 pyplot 繪圖模塊
import numpy as np  # 載入數值計算模塊

x = np.random.rand(100) # 隨機在 0 到 1 之間生成 100 個數值
y = np.random.rand(100) # 隨機在 0 到 1 之間生成 100 個數值
colors = np.random.rand(100) # 隨機在 0 到 1 之間生成 100 個數值
size = np.random.normal(20, 30, 100) # 隨機在 20 到 30 之間生成 100 個數值

# 繪製散點圖
plt.scatter(x, y, s=size, c=colors)
plt.show()

此處輸入圖片的描述

2.3 餅狀圖樣式

餅狀圖通過 matplotlib.pyplot.pie() 繪出。我們也可以進一步設置它的顏色、標籤、陰影等各類樣式。下面就繪出一個示例。

# -*- coding: utf-8 -*

import matplotlib.pyplot as plt

label = 'Cat', 'Dog', 'Cattle', 'Sheep', 'Horse' # 各類別標籤
color = 'r', 'g', 'r', 'g', 'y' # 各類別顏色
size = [1, 2, 3, 4, 5] # 各類別佔比
explode = (0, 0, 0, 0, 0.2) # 各類別的偏移半徑

# 繪製餅狀圖
plt.pie(size, colors=color, explode=explode, labels=label, shadow=True, autopct='%1.1f%%')

# 餅狀圖呈正圓
plt.axis('equal')

# 顯示圖
plt.show()

此處輸入圖片的描述

2.4 組合圖

上面演示了三種常見圖像的繪製。實際上,我們往往會遇到將幾種類型的一樣的圖放在一張圖內顯示,也就是組合圖的繪製。

其實很簡單,你只需要將需要或者的組合圖樣式放在一起就好了,比如柱形圖和折線圖。

# -*- coding: utf-8 -*

import matplotlib.pyplot as plt

x = [1, 3, 5, 7, 9, 11, 13, 15, 17, 19]
y_bar = [3, 4, 6, 8, 9, 10, 9, 11, 7, 8]
y_line = [2, 3, 5, 7, 8, 9, 8, 10, 6, 7]

plt.bar(x, y_bar)
plt.plot(x, y_line, '-o', color='y')
plt.show()

此處輸入圖片的描述

2.5 子圖繪製

上面提到了組合圖繪製,但有一些圖是無法組合直接放在一起的,這時就需要子圖了。子圖,就是將幾張獨立的圖放在一張大圖中呈現。在一些需要對比的情形下,子圖非常有效。

Matplotlib 中,繪製子圖的方法爲matplotlib.pyplot.subplot(),我們通過該方法來控制各子圖的顯示順序。其中:

subplot(行序號, 列序號, 圖序號)

下面列舉了三種常見子圖的位置關係示意圖。

此處輸入圖片的描述

接下來,我們繪製了一個由 4 個子圖(2 行 x 2 列)組成的大圖。

import numpy as np
import matplotlib.pyplot as plt

# 生成數據
x = np.linspace(-2*np.pi, 2*np.pi) 

y1 = np.sin(x)
y2 = np.cos(x)

# 子圖 1
plt.subplot(2, 2, 1)
plt.plot(x, y1, 'k')
# 子圖 2
plt.subplot(2, 2, 2)
plt.plot(x, y2, 'r')
# 子圖 3
plt.subplot(2, 2, 3)
plt.plot(x, y2, 'y')
# 子圖 4
plt.subplot(2, 2, 4)
plt.plot(x, y2, 'g')

plt.show()

此處輸入圖片的描述

除了這類平行或垂直排列的子圖,我們還可以通過 matplotlib.pyplot.subplot()繪製出更復雜的樣式。比如,大圖套小圖。

import numpy as np
import matplotlib.pyplot as plt

# 生成數據
x = np.linspace(-2 * np.pi, 2 * np.pi)

y1 = np.sin(x)
y2 = np.cos(x)

# 大圖
plt.axes([.1, .1, .8, .8])
plt.plot(x, y1, 'k')
# 小圖
plt.axes([.6, .6, .3, .3])
plt.plot(x, y2, 'r')

plt.show()

此處輸入圖片的描述

2.6 繪製圖例

一般情況下,當繪製好圖案後,還需要繪製圖例。Matplotlib 中,圖例可以通過 matplotlib.pyplot.legend() 方法繪製。我們又拿上面的正弦和餘弦曲線舉例。

# -*- coding: utf-8 -*

from matplotlib import pyplot as plt  # 載入 pyplot 繪圖模塊
import numpy as np  # 載入數值計算模塊

# 生成數據
X = np.linspace(-2 * np.pi, 2 * np.pi, 1000)
y1 = np.sin(X)
y2 = np.cos(X)

# 使用 label= 添加標籤
plt.plot(X, y1, color='r', linestyle='--', linewidth=2, label='sin 函數')
plt.plot(X, y2, color='b', linestyle='-', linewidth=2, label='cos 函數')
# 繪製圖例
plt.legend(loc='upper left')
plt.show()

在這裏,我們需要修改兩個地方,也就是通過 label= 爲每一條曲線添加標籤。然後,增加一條 plt.legend(loc='upper left') 就可以了。其中,loc='upper left' 是指明圖例的位置,例如這裏是左上方。你還可以通過 down 和 right 組合實現位置的變換。

上方繪製出來的最終圖像如下所示:

此處輸入圖片的描述

當然,這只是圖例中的樣式之一。你可以瀏覽官方文檔 1237 頁查看其他樣式的繪製方法。

2.7 圖像標註

當我們繪製一些較爲複雜的圖像時,閱讀對象往往很難全面理解圖像的含義。而此時,圖像標註往往會起到畫龍點睛的效果。圖像標註,就是在畫面上添加文字註釋、指示箭頭、圖框等各類標註元素。

Matplotlib 中,文字標註的方法由 matplotlib.pyplot.text() 實現。最基本的樣式爲 matplotlib.pyplot.text(x, y, s),其中 x, y 用於標註位置定位,s 代表標註的字符串。除此之外,你還可以通過 fontsize= , horizontalalignment= 等參數調整標註字體的大小,對齊樣式等。

下面,我們舉一個對柱形圖進行文字標註的示例。

# -*- coding: utf-8 -*
from matplotlib import pyplot as plt # 載入繪圖模塊

x_bar = [10, 20, 30, 40, 50] #柱形圖橫座標
y_bar = [0.5, 0.6, 0.7, 0.4, 0.6] #柱形圖縱座標
bars = plt.bar(x_bar, y_bar, color='blue', label=x_bar, width=2) # 繪製柱形圖
for i, rect in enumerate(bars):
    x_text = rect.get_x() # 獲取柱形圖橫座標
    y_text = rect.get_height() + 0.01 # 獲取柱子的高度並增加 0.01
    plt.text(x_text, y_text, '%.1f' % y_bar[i]) # 標註文字

plt.show()

此處輸入圖片的描述

除了文字標註之外,還可以通過 matplotlib.pyplot.annotate() 方法向圖像中添加箭頭等樣式標註。接下來,我們向上面的例子中增添一行增加箭頭標記的代碼。

# -*- coding: utf-8 -*
from matplotlib import pyplot as plt # 載入繪圖模塊

x_bar = [10, 20, 30, 40, 50] #柱形圖橫座標
y_bar = [0.5, 0.6, 0.7, 0.4, 0.6] #柱形圖縱座標
bars = plt.bar(x_bar, y_bar, color='blue', label=x_bar, width=2) # 繪製柱形圖
for i, rect in enumerate(bars):
    x_text = rect.get_x() # 獲取柱形圖橫座標
    y_text = rect.get_height() + 0.01 # 獲取柱子的高度並增加 0.01
    plt.text(x_text, y_text, '%.1f' % y_bar[i]) # 標註文字

    # 增加箭頭標註
    plt.annotate('Max', xy=(32, 0.6), xytext=(38, 0.6), arrowprops=dict(facecolor='black', width=1, headwidth=7))

plt.show()

此處輸入圖片的描述

上面的示例中,xy=() 表示標註終點座標,xytext=() 表示標註起點座標。另外,arrowprops=() 用於設置箭頭樣式,facecolor= 設置顏色,width= 設置箭尾寬度,headwidth= 設置箭頭寬度。

在箭頭繪製的過程中,還有一個 arrowstyle= 用於改變箭頭的樣式。下圖展示了常見的箭頭樣式。

此處輸入圖片的描述

另外,connectionstyle= 的參數可以用於更改箭頭連接的樣式。下圖展示了常見的箭頭連接樣式。

此處輸入圖片的描述

2.8 動態圖繪製

動態圖是繪圖中不可缺少的一部分,雖然演示環境要求高且使用頻率低,但在一些特定的場景下,動圖傳達的信息量遠大於靜態圖片。

舉個例子來講,數值計算中,我們往往會使用到梯度下降法。如果用語言和公式描述梯度下降的過程,會非常枯燥。要是通過繪製一張演示梯度下降過程的動圖,就算第一次接觸該方法,也會很快的理解。

Matplotlib 很早開始就支持動態圖了,下面就通過簡單的小例子來演示一下動態圖的繪製。

動態圖主要是通過 animation 模塊實現。具體就是 matplotlib.animation.FuncAnimation(fig, func)。其中,fig 代表所繪製的圖像。而 func 可以看作是更新函數,它刷新每一幀的值。

# -*- coding: utf-8 -*
# 載入模塊
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation

# 生成數據並建立繪製類型的圖像
fig, ax = plt.subplots()

x = np.arange(0, 2 * np.pi, 0.01)

line, = plt.plot(x, np.sin(x))

# 更新函數
def update(i):
    line.set_ydata(np.sin(x + i / 10.0))
    return line,

# 繪製動圖
animation = animation.FuncAnimation(fig, update)

# 顯示圖
plt.show()

此處輸入圖片的描述

三、實驗總結

本次實驗對 2D 繪圖中,常見方法包含的參數進行的熟悉,方便繪製出樣式更爲複雜的圖像。當然,這些內容依舊較爲初級,可能無法完全滿足實際需要。而真正的繪圖過程中,我們需要從實際需求出發,善於組合 Matplotlib 中提供的繪圖方法,從而畫出更加漂亮的圖像。

四、課後習題

1.親自動手,嘗試通過 Matplotlib 繪製出下圖這副圖像。

此處輸入圖片的描述

上圖參考代碼:

$ wget http://labfile.oss.aliyuncs.com/courses/892/sin_cos_functions.py
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章