Try   HackMD

Matplotlib 繪圖技巧:三張小圖並列

作者:王一哲
日期:2019/2/3

以下是將在三張小圖並列在同一張圖中的作法,部分內容與〈Matplotlib 繪圖技巧:在同一張圖上繪製兩個函數、兩張圖並列〉相似,但使用兩種不同的作法。這次要畫的圖形是在人工神經網路中常用的激勵函數 (activation function):

sigmoid:     f(x)=11+ex
ReLU:     f(x)={0for x<0xfor x0

tanh:     f(x)=tanh(x)

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →
三種激勵函數圖形

方法1: 用 subplot 切換繪圖位置

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()

以下說明程式碼中較特別的部分

  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 張圖。


方法2: 用 plt.subplots

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()

以下說明程式碼中較特別的部分

  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,另外兩張小圖的繪圖方法相同,只需要修改縱軸資料即可。


參考資料

  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