Python Matplotlib初階使用入門教程

0. 前言

本文介紹Python Matplotlib庫的入門求生級使用方法。

為瞭方便以下舉例說明,我們先導入需要的幾個庫。以下代碼在Jupyter Notebook中運行。

%matplotlib inline     
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd

1. 創建Figure的兩種基本方法

1.1 第1種方法

註意,Figure在Matplotlib中是一個專有名詞(後面會有解釋),Matplotlib把你的數據以圖的形式繪制在Figure(比如說,windows, Jupyter wgets, etc.)中。創建一個Figure的基本方式之一就是使用pyplot.subplots.
如下所示,我們用pyplot.subplots創建瞭一個Figure,其中包含一個axes(同樣,這是一個Matplotlib專有名詞,後面再進行解釋),然後再利用axes.plot畫圖。

fig, ax = plt.subplots()  # Create a figure containing a single axes.
x    = np.arange(100)
Fs   = 100  # 100Hz sampling rate
Fsin = 2    # 2Hz 
y = np.sin(2*np.pi*Fsin*(1/Fs)*x)
ax.plot(x, y)  # Plot some data on the axes.

以上代碼畫瞭一個正弦波的波形。

1.2 第2種方法

許多其它的繪圖工具庫或者語言並不要求你必須顯式地(explicity)先創建一個Figure以及axes,比如說在Matlab中,你直接如下所示一樣直接調用plot()函數就一步到位地得到所想要的圖,如果現成的axes的話,matlab會為你創建一個.

plot([1, 2, 3, 4], [1, 4, 2, 3]) % MATLAB plot.

事實上,你也可以以這種方式使用Matplotlib。對於每一個axes的繪圖方法,matplotlib.pyplot模塊中都有一個對應的函數執行在當前axes上畫一個圖的功能,如果還沒有已經創建好的axes的話,就先為你創建一個Figure和axes,正如在Matlab中一樣。因此以上例子可以更簡潔地寫為:

plt.plot(x, y)  # Call plt.plot() directly

同樣會得到以上相同的圖。

2. Figure的解剖圖及各種基本概念

上圖出自Ref1。圖中給出瞭matplotlib中Figure(沒有想好這個到底應該怎麼翻譯。本來想是不是可以譯成畫佈,但是畫佈對應英文中的Canvas。而Figure的說明中明確指出瞭Figure包含瞭Canvas,如果說Canvas是指畫佈的話,那Figure其實是指整個一幅畫。還是不勉強吧,直接用英語單詞好瞭)

2.1 Figure

The whole figure.整幅畫或整個圖。Figure保持其中所有的child axes的信息,以及一些特殊的artists (titles, figure legends, etc)(這裡artist又是很難翻譯的一個詞,指的是標題、圖例等圖的說明性信息對象),以及畫佈(canvas)。
可以說Figure是幕後的大Boss管理著所有的信息,是它真正執行為你繪制圖畫的動作。但是作為用戶,它反而是不太顯眼的,對你來說多少有點隱形的樣子。一個Figure中可以包含任意多個axes,通常至少包含一個。

以下是創建Figure的幾種方式,其中前兩種在上面的例子已經介紹,也是常用的。
最後一種是創建一個空的Figure,可以在之後給它添加axes。這種做法不常見,屬於高階用法,方便高階用戶進行更加靈活的axes佈局。

fig, ax = plt.subplots()  # a figure with a single Axes
fig, axs = plt.subplots(2, 2)  # a figure with a 2x2 grid of Axes
fig = plt.figure()  # an empty figure with no Axes

2.2 Axes

Axes原本是axis(坐標)的復數,所以可以翻譯成坐標系?就這麼理解著吧。一個給定的Figure可以包含多個axes,但是一個axes對象隻能存在於一個Figure中。(按坐標系理解的話,故名思意)一個Axes包含多個axis,比如說在2D(2維)的圖中有兩個坐標軸,在3D(3維)圖中有三個坐標軸。
在一個axes中可以通過以下一些方法來設置圖的一些屬性:
set_xlim(),set_ylim():分別用於設置x軸、y軸的表示范圍
set_title():設置圖的標題
set_xlabel(),set_ylabel(): 分別用於設置x軸和y軸的標簽

Axes類和它的成員函數是matplolib的面向對象的界面的主要入口(關於面向對象接口與pyplot接口參見後面的說明)

2.3 Axis

這個就是我們常說的坐標軸。不再贅述。事實上,越解釋越糊塗。。。有興趣的小夥伴可以看看matplotlib文檔的原始說明,反正我是越看越暈。。。還不如直接看代碼例直到怎麼使用就可以瞭。

2.4 Artist

Basically, everything you can see on the figure is an artist (even the Figure, Axes, and Axis objects). This includes Text objects, Line2D objects, collections objects, Patch objects … (you get the ea). When the figure is rendered, all of the artists are drawn to the canvas. Most Artists are tied to an Axes; such an Artist cannot be shared by multiple Axes, or moved from one to another.

暈菜。。。同上,還不如直接看代碼例直到怎麼使用就可以瞭^-^

3. 繪圖函數的輸入

所有的繪圖函數都接受numpy.array or numpy.ma.masked_array作為輸入。
像pandas中的數據對象以及numpy.matrix等類似於數組(’array-like’)的對象如果直接用於繪圖函數的輸入的話有可能會產生意想不到的結果。所以最好把它們先轉換成numpy.array對象再傳遞給繪圖函數。

# For example, to convert a pandas.DataFrame
a = pd.DataFrame(np.random.rand(4, 5), columns = list('abcde'))
a_asarray = a.values
 
# and to convert a numpy.matrix
b = np.matrix([[1, 2], [3, 4]])
b_asarray = np.asarray(b)

4. 面向對象接口與pyplot接口

如上所述,有兩種基本的使用Matplotlib的方法。

(1) 顯式地創建Figure和axes,然後調用方法作用於它們,這個稱之為面向對象風格。

(2) 直接調用pyplot進行繪圖,這個姑且稱之為快捷風格吧

面向對象風格的使用方法示例:

x = np.linspace(0, 2, 100)
 
# Note that even in the OO-style, we use `.pyplot.figure` to create the figure.
fig, ax = plt.subplots()  # Create a figure and an axes.
ax.plot(x, x, label='linear')  # Plot some data on the axes.
ax.plot(x, x**2, label='quadratic')  # Plot more data on the axes...
ax.plot(x, x**3, label='cubic')  # ... and some more.
ax.set_xlabel('x label')  # Add an x-label to the axes.
ax.set_ylabel('y label')  # Add a y-label to the axes.
ax.set_title("Simple Plot")  # Add a title to the axes.
ax.legend()  # Add a legend.

快捷(pyplot)風格的使用方法示例:

x = np.linspace(0, 2, 100)
 
plt.plot(x, x, label='linear')  # Plot some data on the (implicit) axes.
plt.plot(x, x**2, label='quadratic')  # etc.
plt.plot(x, x**3, label='cubic')
plt.xlabel('x label')
plt.ylabel('y label')
plt.title("Simple Plot")
plt.legend()

以上代碼中同時給出瞭兩種風格中的label、title、legend等設置的方法或函數使用例。

以上兩段代碼示例產生同樣的繪圖效果:

此外,還有第三種方法,用於在GUI應用中的嵌入式Matplotlib。這個屬於進階用法,在本文就不做介紹瞭。

面向對象風格和pyplot風格功能相同同樣好用,你可以選擇使用任何一種風格。但是最好選定其中一種使用,不要昏庸。一般來說,建議僅在交互式繪圖(比如說在Jupyter notebook)中使用pyplot風格,而在面向非交互式繪圖中則推薦使用面向對象風格。

註意,在一些比較老的代碼例中,你還可以看到使用pylab接口。但是現在不建議這樣用瞭(This approach is strongly discouraged nowadays and deprecated)。這裡提一嘴隻是因為偶爾你還可能看到它,但是,在新的代碼不要用就好瞭。

5. 繪圖復用實用函數例

通常我們會發現需要重復繪制很多相類似的圖,隻是采用不同的數據而已。為瞭提高效率減少錯誤,可以考慮將一些繪圖處理封裝成一個函數,以便於重復使用,避免過多的冗餘代碼。以下是一個這樣的模板例子:

def my_plotter(ax, data1, data2, param_dict):
    """
    A helper function to make a graph
    Parameters
    ----------
    ax : Axes
        The axes to draw to
    data1 : array
       The x data
    data2 : array
       The y data
    param_dict : dict
       Dictionary of kwargs to pass to ax.plot
    Returns
    -------
    out : list
        list of artists added
    """
    out = ax.plot(data1, data2, **param_dict)
    return out

然後你可以以如下方式使用:

x = np.linspace(0, 5, 20)
fig, ax = plt.subplots()
x2 = x**2
x3 = x**3
my_plotter(ax, x, x2, {'marker': 'o'})
my_plotter(ax, x, x3, {'marker': 'd'})

或者,如果你需要多個子圖的話,

x = np.linspace(0, 5, 20)
x2 = x**2
x3 = x**3
fig, (ax1, ax2) = plt.subplots(1, 2)
my_plotter(ax1, x, x2, {'marker': 'x'})
my_plotter(ax2, x, x3, {'marker': 'o'})
 
fig, ax = plt.subplots(1, 2)
my_plotter(ax[0], x, x2, {'marker': 'x'})
my_plotter(ax[1], x, x3, {'marker': 'o'})

註意,如以上代碼例所示,當創建瞭多個子圖時,有兩種引用axes的方式。第一種方式中,創建時直接將兩個axes(每個子圖對應一個axes)賦給ax1和ax2。第一種方式中,創建時直接將兩個axes賦給一個axes數組ax,然後以ax[0]和ax[1]的格式進行引用。

Ref1: Usage Gue — Matplotlib 3.4.3 documentation

到此這篇關於Python Matplotlib初階使用入門的文章就介紹到這瞭,更多相關Python Matplotlib使用入門內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!

推薦閱讀: