python plt.subplot_Python Matplotlib subplot函数详解:创建子图
使用 Matplotlib 除可以生成包含多條折線的復式折線圖之外,它還允許在一張數據圖上包含多個子圖。
調用 subplot() 函數可以創建一個子圖,然后程序就可以在子圖上進行繪制。subplot(nrows, ncols, index, **kwargs) 函數的 nrows 參數指定將數據圖區域分成多少行;ncols 參數指定將數據圖區域分成多少列;index 參數指定獲取第幾個區域。
subplot() 函數也支持直接傳入一個三位數的參數,其中第一位數將作為 nrows 參數;第二位數將作為 ncols 參數;第三位數將作為 index 參數。
下面程序示范了生成多個子圖:
import matplotlib.pyplot as plt import numpy as np plt.figure() # 定義從-pi到pi之間的數據,平均取64個數據點 x_data = np.linspace(-np.pi, np.pi, 64, endpoint=True) # ① # 將整個figure分成兩行兩列,第三個參數表示該圖形放在第1個網格 plt.subplot(2, 2, 1) # 繪制正弦曲線 plt.plot(x_data, np.sin(x_data)) plt.gca().spines['right'].set_color('none') plt.gca().spines['top'].set_color('none') plt.gca().spines['bottom'].set_position(('data', 0)) plt.gca().spines['left'].set_position(('data', 0)) plt.title('正弦曲線') # 將整個figure分成兩行兩列,并將該圖形放在第2個網格 plt.subplot(222) # 繪制余弦曲線 plt.plot(x_data, np.cos(x_data)) plt.gca().spines['right'].set_color('none') plt.gca().spines['top'].set_color('none') plt.gca().spines['bottom'].set_position(('data', 0)) plt.gca().spines['left'].set_position(('data', 0)) plt.title('余弦曲線') # 將整個figure分成兩行兩列,并該圖形放在第3個網格 plt.subplot(223) # 繪制正切曲線 plt.plot(x_data, np.tan(x_data)) plt.gca().spines['right'].set_color('none') plt.gca().spines['top'].set_color('none') plt.gca().spines['bottom'].set_position(('data', 0)) plt.gca().spines['left'].set_position(('data', 0)) plt.title('正切曲線') plt.show()
上面程序多次調用 subplot() 函數來生成子圖,每次調用 subplot() 函數之后的代碼表示在該子圖區域繪圖。上面程序將整個數據圖區域分成 2×2 的網格,程序分別在第 1 個網格中繪制正弦曲線,在第 2 個網格中繪制余弦曲線,在第 3 個網格中繪制正切曲線。
可能有讀者感到疑問,plot() 函數不是用于繪制折線圖的嗎?怎么此處還可用于繪制正弦曲線、余弦曲線呢?
其實此處繪制的依然是折線圖。看程序中的 ① 號代碼調用 numpy 的 linspace() 函數生成了一個包含多個數值的列表,該數值列表的范圍是從 -pi 到 pi,平均分成 64 個數據點,程序中用到的 numpy.sin()、numpy.cos()、numpy.tan() 等函數也返回一個列表:傳入這些函數的列表包含多少個值,這些函數返問的列表也包含多少個值。
這意味著上面程序所給制的折線圖會包含 64 個轉折點,由于這些轉折點非常密集,看上去顯得比較光滑,因此就變成了曲線。
如果讀者將程序中x_data=np.linespace(-np.pi,np.pi,64,endpoint = True)代碼的 64 改為4、6等較小的數,將會看到程序繪制的依然是折線圖。
運行上面程序,可以看到如圖 1 所示的效果。
圖 1 生成多個子圖
如圖 1 所示的顯示效果比較差,程序明明只要顯示 3 個子圖,但第 4 個位置被空出來了,能不能讓某個子圖占多個網格昵?答案是肯定的,程序做好控制即可。例如,將上面程序改為如下形式:
import matplotlib.pyplot as plt import numpy as np plt.figure() # 定義從-pi到pi之間的數據,平均取64個數據點 x_data = np.linspace(-np.pi, np.pi, 64, endpoint=True) # ① # 將整個figure分成兩行一列,第三個參數表示該圖形放在第1個網格 plt.subplot(2, 1, 1) # 省略繪制正弦曲線 ... # 將整個figure分成兩行兩列,并將該圖形放在第4個網格 plt.subplot(223) # 省略繪制余弦曲線 ... # 將整個figure分成兩行兩列,并該圖形放在第4個網格 plt.subplot(224) #省略繪制正切曲線 ... plt.show()
上面程序中第 8 行代碼將整個區域分成兩行一列,并指定子圖占用第 1 個網格,也就是整個區域的第一行:第 13 行代碼將整個區域分成兩行兩列,并指定子圖占用第 3 個網格(注意不是第 2 個網絡,因為第一個子圖已經占用了第一行,對于兩行兩列的網格來說,第一個子圖已經占用了兩個網格,因此此處指定子圖占用第 3 個網格,這意味著該子圖在第二行第一格);第 18 行代碼將整個區域分成兩行兩列,并指定子圖占用第 4 個網格,這意味著該子圖會在第二行第二格。
運行上面程序,可以看到如圖 2 所示的效果。
圖 2 控制多個子圖的分布
如果讀者不想這么費勁來計算行、列,將上面程序改為如下形式:
import matplotlib.pyplot as plt import numpy as np import matplotlib.gridspec as gridspec plt.figure() # 定義從-pi到pi之間的數據,平均取64個數據點 x_data = np.linspace(-np.pi, np.pi, 64, endpoint=True) # ① # 將繪圖區域分成2行3列 gs = gridspec.GridSpec(2, 3) # 指定ax1占用第一行(0)整行 ax1 = plt.subplot(gs[0, :]) # 指定ax1占用第二行(1)的第一格(第二個參數0代表) ax2 = plt.subplot(gs[1, 0]) # 指定ax1占用第二行(1)的第二、三格(第二個參數0代表) ax3 = plt.subplot(gs[1, 1:3]) # 繪制正弦曲線 ax1.plot(x_data, np.sin(x_data)) ax1.spines['right'].set_color('none') ax1.spines['top'].set_color('none') ax1.spines['top'].set_color('none') ax1.spines['bottom'].set_position(('data', 0)) ax1.spines['left'].set_position(('data', 0)) ax1.set_title('正弦曲線') # 繪制余弦曲線 ax2.plot(x_data, np.cos(x_data)) ax2.spines['right'].set_color('none') ax2.spines['top'].set_color('none') ax2.spines['bottom'].set_position(('data', 0)) ax2.spines['left'].set_position(('data', 0)) ax2.set_title('余弦曲線') # 繪制正切曲線 ax3.plot(x_data, np.tan(x_data)) ax3.spines['right'].set_color('none') ax3.spines['top'].set_color('none') ax3.spines['bottom'].set_position(('data', 0)) ax3.spines['left'].set_position(('data', 0)) ax3.set_title('正切曲線') plt.show()
上面程序中的第 10 行代碼將繪圖區域分成兩行三列;第 12 行代碼調用 subplot(gs[0,:]),指定 ax1子圖區域占用第一行整行,其中第一個參數 0 代表行號,沒有指定列范圍,因此該子圖在整個第一行;第 14 行代碼調用 subplot(gs[1, 0]),指定 ax2 子圖區域占用第二行的第一格,其中第一個參數 1 代表第二行,第二個參數 0 代表第一格,因此該子圖在第二行的第一格;第 16 行代碼調用 subplot(gs [1 , 1 : 3]),指定 ax3 子圖區域占用第二行的第二格到第三格,其中第一個參數 1 代表第二行,第二個參數 1:3 代表第二格到第三格,因此該子圖在第二行的第二格到第三格。
定義完 ax1、ax2、ax3 這 3 個子圖所占用的區域之后,接下來程序就可以通過 ax1、ax2、ax3 的方法在各自的子圖區域繪圖了。運行上面程序,可以看到如圖 3 所示的效果。
圖 3 使用 GridSpec 管理子圖的分布
總結
以上是生活随笔為你收集整理的python plt.subplot_Python Matplotlib subplot函数详解:创建子图的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 记一次磁盘扩容失败并恢复
- 下一篇: 2021年5月29日【Jiawei_Z】