# Matplotlib 繪圖技巧:三張小圖並列 > 作者:王一哲 > 日期:2019/2/3 以下是將在三張小圖並列在同一張圖中的作法,部分內容與〈[Matplotlib 繪圖技巧:在同一張圖上繪製兩個函數、兩張圖並列](https://hackmd.io/s/Bkd0EMyCm)〉相似,但使用兩種不同的作法。這次要畫的圖形是在人工神經網路中常用的激勵函數 (activation function): $$sigmoid:~~~~~f(x) = \frac{1}{1 + e^{-x}}$$ $$ReLU:~~~~~f(x) = \left\{\begin{matrix} 0 & \mathrm{for}~x < 0\\ x & \mathrm{for}~x \ge 0 \end{matrix}\right.$$ $$tanh:~~~~~f(x) = tanh(x)$$ <img height="100%" width="100%" src="https://i.imgur.com/LsiGJpy.png" style="display: block; margin-left: auto; margin-right: auto;"/> <div style="text-align:center">三種激勵函數圖形</div> </br> ## 方法1: 用 subplot 切換繪圖位置 ```python= import matplotlib.pyplot as plt import numpy as np # 產生陣列x, sigmoid, relu, tanh xmin, xmax, num = -6, 6, 200 x = np.linspace(xmin, xmax, num) sigmoid = 1 / (1 + np.exp(-x)) # 不能寫成 relu = x, 這樣會改變 x 的數值 relu = x.copy() relu[np.where(relu < 0)] = 0 tanh = np.tanh(x) plt.figure(figsize = (12, 3), dpi = 72) plt.subplots_adjust(left = 0.1, bottom = 0.2, right = 0.9, top = 0.9, wspace = 0.4, hspace = 0.1) plt.subplot(131) plt.plot(x, sigmoid, color = 'blue', linestyle = '-', linewidth = 3) plt.xlabel('x', fontsize = 14) plt.ylabel('f(x)', fontsize = 14) plt.xlim(xmin,xmax) plt.tick_params(axis = 'both', which = 'major', labelsize = 10) plt.title('Sigmoid', fontsize = 14) plt.grid('on') plt.subplot(132) plt.plot(x, relu, color = 'blue', linestyle = '-', linewidth = 3) plt.xlabel('x', fontsize = 14) plt.ylabel('f(x)', fontsize = 14) plt.xlim(xmin,xmax) plt.tick_params(axis = 'both', which = 'major', labelsize = 10) plt.title('ReLU', fontsize = 14) plt.grid('on') plt.subplot(133) plt.plot(x, tanh, color = 'blue', linestyle = '-', linewidth = 3) plt.xlabel('x', fontsize = 14) plt.ylabel('f(x)', fontsize = 14) plt.xlim(xmin,xmax) plt.tick_params(axis = 'both', which = 'major', labelsize = 10) plt.title('tanh', fontsize = 14) plt.grid('on') plt.savefig('subplots.svg') plt.savefig('subplots.png') plt.show() ``` </br> 以下說明程式碼中較特別的部分 1. 產生陣列 relu 時分為兩個步驟,先用 **relu = x.copy()** 將 x 的值複製給 relu,如果寫成 **relu = x**,之後變 relu 的數值時 x 的數值會跟著變化;接著再用 **relu[np.where(relu < 0)] = 0** 將小於 0 的元素都改成 0。 2. 使用 **plt.subplots_adjust** 調整圖片的空間配置。 3. 使用 **plt.subplot** 切換繪圖的位置,例如 (132) 代表整張圖中有 1 列、3 欄的小圖,目前繪製第 2 張圖。 </br> ## 方法2: 用 plt.subplots ```python= import matplotlib.pyplot as plt import numpy as np # 產生陣列x, sigmoid, relu, tanh xmin, xmax, num = -6, 6, 200 x = np.linspace(xmin, xmax, num) sigmoid = 1 / (1 + np.exp(-x)) # 不能寫成 relu = x, 這樣會改變 x 的數值 relu = x.copy() relu[np.where(relu < 0)] = 0 tanh = np.tanh(x) fig, (ax1, ax2, ax3) = plt.subplots(1, 3, sharex = True, figsize=(12, 3), dpi = 72) fig.subplots_adjust(left = 0.1, bottom = 0.2, right = 0.9, top = 0.9, wspace = 0.4, hspace = 0.1) ax1.plot(x, sigmoid, color = 'blue', linestyle = '-', linewidth = 3) ax1.set_xlabel('x', fontsize = 14) ax1.set_ylabel('f(x)', fontsize = 14) ax1.set_xlim(xmin,xmax) ax1.tick_params(axis = "both", labelsize = 10) ax1.set_title('Sigmoid', fontsize = 14) ax1.grid('on') ax2.plot(x, relu, color = 'blue', linestyle = '-', linewidth = 3) ax2.set_xlabel('x', fontsize = 14) ax2.set_ylabel('f(x)', fontsize = 14) ax2.tick_params(axis = "both", labelsize = 10) ax2.set_title('ReLU', fontsize = 14) ax2.grid('on') ax3.plot(x, tanh, color = 'blue', linestyle = '-', linewidth = 3) ax3.set_xlabel('x', fontsize = 14) ax3.set_ylabel('f(x)', fontsize = 14) ax3.tick_params(axis = "both", labelsize = 10) ax3.set_title('tanh', fontsize = 14) ax3.grid('on') fig.savefig('subplots.svg') fig.savefig('subplots.png') fig.show() ``` </br> 以下說明程式碼中較特別的部分 1. 使用 **fig, (ax1, ax2, ax3) = plt.subplots(1, 3, sharex = True, figsize=(12, 3), dpi = 72)** 產生繪圖物件 fig,其中共有 1 列、3 欄的小圖,3 張小圖的名稱依序為 ax1、ax2、ax3,並且 3 張小圖共用相同的 x 軸。 2. 使用 **ax1.plot(x, sigmoid, color = 'blue', linestyle = '-', linewidth = 3)** 繪製第 1 張小圖,橫軸為 x,縱軸為 sigmoid,另外兩張小圖的繪圖方法相同,只需要修改縱軸資料即可。 </br> ## 參考資料 1. **plt.subplots_adjust**: https://matplotlib.org/api/_as_gen/matplotlib.pyplot.subplots_adjust.html 2. **plt.subplots**: https://matplotlib.org/api/_as_gen/matplotlib.pyplot.subplots.html --- ###### tags:`Python`