1 figure
1.1 創建figure
在上文中我們一直提到的figure指的是Figure類的實例化對象,當然我們一般不會直接去實例化Figure類,因爲這樣創建的Figure實例對象不能納入序列中共同管理。matplotlib中提供了多種方法創建figure,其中屬pyplot模塊中的figure()方法最常用也最方便,下面我們來說說這個方法。figure方法參數如下:
- num:整型或字符串類型,可選參數,默認爲None。這個參數課可以理解爲是figure的身份標識,即id。當值爲None時,會創建一個figure實例,該實例的num值會在已有基礎上自增;當該參數不爲None時,如果與已有的num值重複,則會切換到該figure使其處於激活狀態,並返回一個該figure的引用;如果傳入的參數爲字符串,該字符串將會被設置爲figure的標題。
- figsize:tuple類型,可選參數,默認爲None。通過figsize參數可以設置figure的size,即(width, height),單位爲inch。當值爲None時,採用默認size。
- dpi:整型,可選參數,用於設置圖片像素。
- facecolor:可選參數,用於設置前景色,默認爲白色。
- edgecolor:可選參數,用於設置邊框顏色,默認爲黑色。
- frameon:bool類型,可選參數,表示是否繪製窗口的圖框,默認是。
- FigureClass:傳入一個類名,當使用自定義的類實例化figure時使用,默認爲matplotlib.figure.Figure。
- clear:bool類型,可選參數,默認爲False。如果值爲True的話,如果figure已存在,則會清除該figure的全部內容。
from matplotlib import pyplot as plt import matplotlib as mpl import numpy as np mpl.rcParams['font.sans-serif'] = ['SimHei'] # 中文字體支持
fig = plt.figure(figsize=(4,2), facecolor='grey') # 創建figure fig.add_axes((0,0,1,1)) # 必須添加axes後才能顯示 plt.show()
在jupyter編輯器中,空白的figure是不會顯示的,所以必須在figure中至少添加一個axes。
1.2 figure的常用設置
1.2.1 set方法通用設置
創建figure時的各個參數基本都可以通過figure實例對象中對應的對應的set方法進行修改,例如set_facecolor()用來設置前景色,set_size_inches()用來設置大小等。設置前景色:
fig = plt.figure(figsize=(4,2)) fig.set_facecolor('grey') # 設置前景色 plt.plot() plt.show()
fig = plt.figure() fig.set_size_inches(2,3) # 設置大小 plt.plot() plt.show()
1.2.2 設置figure標題
fig = plt.figure(figsize=(4,2)) fig.suptitle("figure title", color='red') # 設置figure標題 plt.plot() plt.show()
1.2.3 添加文本
fig = plt.figure(figsize=(4,2)) fig.text(0.5,0.5,"figure text",color='red') # 設置figure標題,前兩個參數分別表示到左邊框和上邊框的百分比距離 plt.plot() plt.show()
1.2.4 設置圖例
fig = plt.figure(figsize=(5,3)) axes = fig.add_axes((0,0,0.8,1)) x = np.linspace(0, 10, 1000) line1, = axes.plot(x, np.sin(x)) # 注意,line1後面有個逗號,因爲plot()方法返回值是一個列表 line2, = axes.plot(x, np.cos(x)) fig.legend([line1, line2],['sin', 'cos']) plt.show()
1.2.5 設置子圖間距
fig, axes = plt.subplots(2,2,facecolor='grey') fig.subplots_adjust(left=None, # 設置畫圖區域與figure上下左右邊框的比例距離 bottom=None, right=None, top=None, wspace=0.3, # 子圖間水平方向距離 hspace=1) # 子圖間垂直方向距離 plt.show()
2 axes
axes可以認爲是figure這張畫圖上的子圖,因爲子圖上一般都是座標圖,所以我更願意理解爲軸域或者座標系。
2.1 創建axes
一個figure可以有多個axes, 無論是pyplot模塊還是figure實例內都定義有多種創建axes的方法。(1) plt.axes()plt.axes()是指pyplot模塊中的axes()方法,該方法會在當前激活的figure中創建一個axes,並使創建好的axes處於激活狀態。當傳入的第一個位置參數爲空時,該方法會創建一個佔滿整個figure的axes;通常我們可以傳入一個tuple參數(left, botton, width, height)作爲第一個位置參數,tuple中四個元素分別表示與figure左邊框比例距離,邊框寬度佔figure寬度的比例,寬度比例,高度佔figure高度的比例。通過這種方式添加axes時,matplotlib會自動創建一個axes,然後將創建好的axes按照給定的位置和size添加到figure中,最後返回一個axes的引用。
fig1 = plt.figure(figsize=(4,2), facecolor='grey') ax1 = plt.axes((0.1, 0.1, 0.8, 0.7), facecolor='green') fig2 = plt.figure(figsize=(4,2), facecolor='yellow') ax2 = plt.axes((0.1, 0.1, 0.8, 0.8), facecolor='red') # 這個axes將會被覆蓋在下面 plt.show()
注意,如果在相同區域添加axes,後面添加的axes會把前面添加的axes覆蓋。
fig = plt.figure(figsize=(4,2), facecolor='grey') ax1 = plt.axes((0.1, 0.1, 0.8, 0.8), facecolor='green') ax2 = plt.axes((0.1, 0.1, 0.8, 0.7), facecolor='red') # 這個axes將會被覆蓋在下面 plt.show()
(2) figure.add_axes()figure.add_axes()方法的作用是將一個axes添加到figure中,這一方法可以傳入一個已創建好的axes作爲第一個參數,add_axes會將傳入的axes添加到figure中,但這種情況使用不多。在大多數情況下,我們會如同上述在plt.axes()方法中那樣傳遞一個tuple參數(left, botton, width, height)作爲第一個位置參數。同樣,如果在相同區域添加axes,後面添加的axes會把前面添加的axes覆蓋。
fig = plt.figure(figsize=(4,2), facecolor='grey') fig.add_axes((0.1, 0.1, 0.3, 0.7), facecolor='green') # 這個axes將會被覆蓋在下面 fig.add_axes((0.5, 0.1, 0.3, 0.7), facecolor='red') plt.show()
(3) plt.subplot與plt.subplots()
plt.subplot和plt.subplots()是在pyplot模塊中定義的兩個方法,兩個方法都是將figure劃分爲多行多列的網格,然後添加axes,但功能和用法卻有些許不同。
- plt.subplot()
plt.subplot主要包括三個參數(nrows, ncols, index),分別表示行數、列數和索引,該方法會根據指定的行列數對figure劃分爲網格,讓後在指定索引的網格中創建axes,並返回該axes的引用。索引是從1開始從左往右,從上到下遞增,例如plt.subplot(2,2,4)表示將figure劃分爲兩行兩列的4個網格,並在第4個子網格中創建一個axes然後返回。注意,每一次調用plt.subplot()方法只會在指定索引的子網格中創建axes,而不是在所有子網格中都創建axes,如果需要在多個子網格中創建axes,那麼就需要多次調用plt.subplot()指定不同的索引。另外,如果nrows, ncols, index三個參數都小於10,可以將這三個參數合併成一個3位整數來寫,例如plt.subplot(2,2,4)與plt.subplot(224)是完全等效的。
fig = plt.figure(figsize=(4,4), facecolor='grey') ax1 = plt.subplot(221,facecolor='green') ax2 = plt.subplot(224,facecolor='red') plt.show()
- plt.subplots()
與plt.subplot()不同的是,plt.subplots()會重新創建一個figure,然後將創建好的figure按照指定的行列數劃分爲網格,並在每一個子網格中各創建一個axes,最終同時返回figure和所有子網格中axes組成的numpy數組中。
fig, axes = plt.subplots(2,2,facecolor='grey') fig.suptitle('figure title') print(type(axes)) axes[0,0].set_facecolor('green') axes[1,1].set_facecolor('red') plt.show()
<class 'numpy.ndarray'>
plt.subplots()還有一對參數sharex, sharey用於設置是否共享x軸或y軸,這對參數有取值可以使bool型或'none', 'all', 'row', 'col'這4個字符串中的一個,分別有以下含義:
- False 和 'none'表示不共享,任何子圖中的x軸或y軸都是相互獨立的;
- True 和 'all'表示所有子圖共享x軸或y軸;
- 'row' 表示同一行的子圖共享x軸或y軸;
- 'col' 表示同一列的子圖共享x軸或y軸;
fig, axes = plt.subplots(2,2,sharex=True,sharey=True,facecolor='grey') fig.suptitle('figure title') axes[0,0].set_facecolor('green') axes[1,1].set_facecolor('red') plt.show()
(4) figure.add_subplot()與figure.subplots()figure.add_subplot與上文中介紹過的plt.subplot()無論是功能還是使用方法上都是幾乎一樣的,唯一區別就是plt.subplot()的目標是在當前激活的figure,而figure.add_subplot()是調用add_subplot()方法的figure。
fig = plt.figure(figsize=(4,4), facecolor='grey') ax1 = fig.add_subplot(221,facecolor='green') ax2 = fig.add_subplot(224,facecolor='red') plt.show()
figure.subplots()的功能、用法又與上文中介紹過的plt.subplots()很相似,區別在於figure.subplots()不會重新創建一個figure,而是對當前的figure進行劃分網格並在每一個網格中都創建一個axes。
fig = plt.figure(facecolor='grey') axes = fig.subplots(2,2) axes[0, 0].set_facecolor('green') axes[1, 1].set_facecolor('red') plt.show()
2.2 axes的常用設置
axes是matplotlib作圖中衆多元素的核心,可以說,大多數的設置都可以通過axes來完成。
2.2.1 設置標題
fig = plt.figure(facecolor='grey') fig.suptitle("figure 標題", color='red') ax1 = fig.add_subplot(121) ax2 = fig.add_subplot(122) ax1.set_title(' 圖 1') # 設置標題 ax2.set_title(' 圖 2') plt.show()
2.2.2 設置圖例
fig = plt.figure(figsize=(5,3)) axes = fig.add_axes((0,0,0.8,1)) x = np.linspace(0, 10, 1000) line1, = axes.plot(x, np.sin(x)) line2, = axes.plot(x, np.cos(x)) axes.legend([line1, line2],['正弦', '餘弦']) plt.show()
2.2.3 設置座標軸名稱
fig = plt.figure(figsize=(4,1)) axes = fig.add_axes((0,0,1,1)) axes.set_xlabel('x軸', fontsize=15) axes.set_ylabel('y軸', fontsize=15, color='red') plt.show()
2.2.4 設置座標軸範圍
fig = plt.figure(figsize=(6,2)) axes = fig.add_axes((0,0,0.8,1)) x = np.linspace(-3, 5, 1000) line1, = axes.plot(x, np.sin(x)) axes.set_xlim((-3,5)) # 設置橫座標範圍 axes.set_ylim((-3,3)) # 設置縱座標範圍 plt.show()
2.2.5 隱藏邊框
fig = plt.figure(figsize=(6,2)) axes = fig.add_axes((0,0,0.8,1)) x = np.linspace(-10, 10, 1000) line1, = axes.plot(x, np.sin(x)) axes.set_xlim((-10,10)) # 設置橫座標範圍 axes.set_ylim((-2,2)) # 設置縱座標範圍 axes.spines['right'].set_color('none') #隱藏掉右邊框線 axes.spines['top'].set_color('none') #隱藏掉左邊框線 plt.show()
2.2.6 顯示網格
fig = plt.figure(figsize=(6,2)) axes = fig.add_axes((0,0,0.8,1)) x = np.linspace(-10, 10, 1000) line1, = axes.plot(x, np.sin(x)) axes.set_xlim((-10,10)) # 設置橫座標範圍 axes.set_ylim((-2,2)) # 設置縱座標範圍 axes.grid(True) plt.show()
2.2.7 添加註釋
fig = plt.figure(figsize=(6,2)) axes = fig.add_axes((0,0,0.8,1)) x = np.linspace(-10, 10, 1000) line1, = axes.plot(x, np.sin(x)) axes.set_xlim((-10,10)) # 設置橫座標範圍 axes.set_ylim((-2,2)) # 設置縱座標範圍 axes.grid(True) axes.annotate('原點', xy=(0, 0), # xy是指向點的座標 xytext=(2.5, -1.5), # xytext註釋文字的座標 arrowprops=dict(facecolor='red')) plt.show()
3 axis
axis在matplotlib中是一種類似於座標軸的概念,負責處理軸標籤、刻度線、刻度標籤、網格線的繪製。在大多數情況下,axis我們手動創建,在創建axes時會一併創建axis,通過axes的實例對象即可調用axes內的axis實例。通過axis實例,我們可以實現更加多樣化、細微的圖標操作。通過axes實例可以調用get_xaxis()方法獲取axis實例,然後實現對label等對象的操作。
3.1 axis常用設置
3.1.1 設置座標軸名稱
fig = plt.figure(figsize=(4,2), facecolor='grey') axes = fig.add_axes((0, 0,1,1)) # x軸 axes.get_xaxis().get_label().set_text('x axis') axes.get_xaxis().get_label().set_color('red') axes.get_xaxis().get_label().set_fontsize(16) # y軸 axes.yaxis.get_label().set_text('y axis') axes.yaxis.get_label().set_color('blue') axes.yaxis.get_label().set_fontsize(16) plt.show()
3.1.2 設置座標軸刻度標籤樣式
fig = plt.figure(figsize=(4,2), facecolor='grey') axes = fig.add_axes((0, 0,1,1)) # 設置x軸刻度標籤 for tl in axes.get_xaxis().get_ticklabels(): tl.set_color('red') tl.set_rotation(45) tl.set_fontsize(16) plt.show()
3.1.3 設置座標軸刻度位置
import matplotlib.ticker as ticker # Fixing random state for reproducibility np.random.seed(19680801) fig, ax = plt.subplots() ax.plot(100*np.random.rand(20)) formatter = ticker.FormatStrFormatter('$%1.2f') ax.yaxis.set_major_formatter(formatter) for tick in ax.yaxis.get_major_ticks(): tick.label1.set_visible(False) tick.label2.set_visible(True) tick.label2.set_color('green') plt.show()
3.1.4 設置座標軸位置
fig = plt.figure(figsize=(6,2)) axes = fig.add_axes((0,0,0.8,1)) x = np.linspace(-10, 10, 1000) line1, = axes.plot(x, np.sin(x)) axes.set_xlim((-10,10)) # 設置橫座標範圍 axes.set_ylim((-2,2)) # 設置縱座標範圍 axes.spines['right'].set_color('none') #隱藏掉右邊框線 axes.spines['top'].set_color('none') #隱藏掉左邊框線 axes.xaxis.set_ticks_position('bottom') #設置座標軸位置 axes.yaxis.set_ticks_position('left') #設置座標軸位置 axes.spines['bottom'].set_position(('data', 0)) #綁定座標軸位置,data爲根據數據自己判斷 axes.spines['left'].set_position(('data', 0)) plt.show()
4 總結
本文主要介紹matplotlib圖表的三種容器元素:figure、axes、axis。figure是最底層的容器,相當於一張畫布,在畫布上,我們可以畫多個axes,axes就是figure上的子圖,每個axes都是一張獨立的圖表,每個axes包含多個axis,通過axis我們可以實現對圖表更多細節上的操作。理解了matplotlib圖表三個層次的佈局,我們就可以通過figure -> axes --> axis的流程完成圖表在宏觀層面的創建。在後續的博客中,將會繼續介紹對圖表更多更加細節化的設置以及如何畫各種不同的統計圖表。