2018年11月20日 星期二

Matplotlib 繪圖技巧:在同一張圖上繪製兩個函數、兩張圖並列

我們在〈冰與水蒸氣混合達熱平衡時溫度與質量比值關係圖〉中使用 Matplotlib 繪製單一的函數圖形,但如果我們想在同一張圖上繪製兩個函數,或是將兩張圖並列畫在同一張圖片中時要怎麼做呢?

我們以兩個點電荷之間的靜電力和電位能與距離的關係為例,假設點電荷的電量分別為 Q 和 q,兩者之間的距離為 r,則兩者之間的靜電力量值
$$F = \frac{kQq}{r^2}$$
電位能量值
$$U = \frac{kQq}{r}$$
由於使用 Matplotlib 繪圖時必須代入數值,我將數值設定為 $Q = 1 \times 10^{-4} ~\mathrm{C}$、$q = 1 \times 10^{-4} ~\mathrm{C}$、$0.01 \leq r \leq 10~\mathrm{m}$,r 不從 0 開始畫是為了避免靜電力和電位能量值變為無窮大。接著我們來繪製函數圖形。


在同一張圖上繪製兩個函數


我們希望圖片能有以下的特點:

  1. 用不同的顏色繪製不同的函數
  2. 加上圖例、格線、坐標軸標籤
  3. 設定縱軸繪圖範圍

成果如下圖所示,使用的程式碼如下。


在同一張圖上繪製靜電力、電位能與距離的關係圖






"""
 靜電力、電位能對距離的關係圖
 日期: 2018/11/5
 作者: 王一哲
"""
import numpy as np                                        # 引入科學計算函式庫
import matplotlib.pyplot as plt                           # 引入繪圖函式庫

xmin, xmax, num = 0.01, 10, 100                           # 設定繪圖範圍、取點數
x = np.linspace(xmin, xmax, num)                          # 產生x
Q = 1E-4
q = 1E-4
k = 8.988E9
F = k * Q * q / x**2                                      # 靜電力F
U = k * Q * q / x                                         # 電位能U

plt.figure(figsize = (6, 4.5), dpi = 100)                 # 設定圖片尺寸
plt.xlabel('r (m)', fontsize = 16)                        # 設定坐標軸標籤
plt.xticks(fontsize = 12)                                 # 設定坐標軸數字格式
plt.yticks(fontsize = 12)
plt.grid(color = 'red', linestyle = '--', linewidth = 1)  # 設定格線顏色、種類、寬度
plt.ylim(0, 200)                                          # 設定y軸繪圖範圍
# 繪圖並設定線條顏色、寬度、圖例
line1, = plt.plot(x, F, color = 'red', linewidth = 3, label = 'Electric Force (N)')             
line2, = plt.plot(x, U, color = 'blue', linewidth = 3, label = 'Electric Potential Energy (J)')
plt.legend(handles = [line1, line2], loc='upper right')
plt.savefig('Fe_r_plot.svg')                              # 儲存圖片
plt.savefig('Fe_r_plot.png')
plt.show()                                                # 顯示圖片




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

  1. 使用 plt.xlabel('r (m)', fontsize = 16) 設定 x 軸標籤為 r (m),字型大小為 16。
  2. 使用 plt.grid(color = 'red', linestyle = '--', linewidth = 1) 加上格線,格線為紅色虛線,線條寬度為 1。
  3. 使用 plt.ylim(0, 200) 設定y軸繪圖範圍為 1 到 200。
  4. 為了用不同的線條顏色繪製不同的函數,我們使用了以下的程式碼,括號中的選項有:顏色 (color)、線條寬度 (linewidth)、標籤 (label)。由於 plt.plot 的回傳值不是一個單純的物件,如果我們要將繪製的線條物件指定給 line1 和 line2,line1 和 line2 後方一定要加上逗號
  5. line1, = plt.plot(x, F, color = 'red', linewidth = 3, label = 'Electric Force (N)')             
    line2, = plt.plot(x, U, color = 'blue', linewidth = 3, label = 'Electric Potential Energy (J)')
    
  6. 使用 plt.legend(handles = [line1, line2], loc='upper right') 加上圖例,其中 handles 是圖例的內容,在此設定為 line1 和 line2 的標籤;loc是圖例的位置,在此設定為右上方。如果想要知道更詳細的設定,請參考官方說明書 https://matplotlib.org/api/_as_gen/matplotlib.pyplot.legend.html


將兩張圖並列畫在同一張圖片中


我們希望圖片能有以下的特點:

  1. 左、右兩張圖並列
  2. 兩張圖共同相同格式的縱軸
  3. 加坐標軸標籤
  4. 設定縱軸繪圖範圍

成果如下圖所示,使用的程式碼如下。


將靜電力、電位能與距離的關係圖並列於同一張圖中




"""
 靜電力、電位能對距離的關係圖, 兩圖並列
 日期: 2018/11/18
 作者: 王一哲
"""
import numpy as np                   # 引入科學計算函式庫
import matplotlib.pyplot as plt      # 引入繪圖函式庫

xmin, xmax, num = 0.01, 10, 100      # 設定繪圖範圍、取點數
x = np.linspace(xmin, xmax, num)     # 產生x
Q, q, k = 1E-4, 1E-4, 8.988E9        # 點電荷電量及靜電力常數
F = k * Q * q / x**2                 # 靜電力F
U = k * Q * q / x                    # 電位能U

# 建立繪圖物件 fig, 大小為 12 * 4.5, 內有 1 列 2 欄的小圖, 兩圖共用 x 軸和 y 軸
fig, (ax1, ax2) = plt.subplots(1, 2, sharex = True, sharey = True, figsize = (12, 4.5))

# 設定小圖 ax1 的坐標軸標籤, 格線顏色、種類、寬度, y軸繪圖範圍, 最後用 plot 繪圖
ax1.set_xlabel('r (m)', fontsize = 16)
ax1.set_ylabel('F (N)', fontsize = 16)
ax1.grid(color = 'red', linestyle = '--', linewidth = 1)
ax1.set_ylim(0, 200)
ax1.plot(x, F, color = 'blue', linewidth = 3)

# 設定小圖 ax2 的坐標軸標籤, 格線顏色、種類、寬度, 最後用 plot 繪圖
ax2.set_xlabel('r (m)', fontsize = 16)
ax2.set_ylabel('U (J)', fontsize = 16)
ax2.grid(color = 'red', linestyle = '--', linewidth = 1)
ax2.plot(x, U, color = 'blue', linewidth = 3)

# 用 savefig 儲存圖片, 用 show 顯示圖片
fig.savefig('Fe_r_plot_2.svg')
fig.savefig('Fe_r_plot_2.png')
fig.show()




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

  1. 使用 fig, (ax1, ax2) = plt.subplots(1, 2, sharex = True, sharey = True, figsize = (12, 4.5)) 建立多張圖的繪圖物件,其中
    a. 1, 2 代表物件中有 1 列 2 欄的小圖
    b. sharex = True 代表共用 x 軸坐標
    c. sharey = True 代表共用 y 軸坐標
    d. figsize = (12, 4.5) 將物件尺寸設定為 12 吋乘以 4.5 吋。
    e. 整個繪圖物件指定給 fig
    f. 兩張小圖分別指定給 ax1 和 ax2
  2. 使用 ax1.set_xlabel 設定ax1 的 x 坐標軸標籤,使用 ax1.set_ylabel 設定ax1 的 y 坐標軸標籤 ,使用 ax1.set_ylim(0, 200) 設定y軸繪圖範圍為 1 到 200。
  3. ax2 的設定方法與 ax1 相似,但是我們已經設定兩共用 y 軸格式,不需要再設定 ax2.set_ylim(0, 200)。


結語


這是一些使用 Matplotlib 繪圖的筆記,如果想要看更多的繪圖實例,請參考 https://python-graph-gallery.com/


HackMD 版本連結:https://hackmd.io/s/Bkd0EMyCm

沒有留言:

張貼留言