置頂

我的 VPython 教學文件 (HackMD 版本)

VPython 教學文件目錄 安裝及測試 基本語法 等速度直線運動 自由落下 終端速度 水平抛射 使用For迴圈計算水平抛射資料 斜向抛射 圓周運動 簡諧運動 單擺 木塊彈簧系統分離 重力及簡諧 行星運動 相疊木塊 雙重簡諧運動 一維彈性碰撞 ...

熱門文章

2018年6月13日 星期三

使用 matplotlib 繪製函數及數據圖

使用 matplotlib 繪製函數及數據圖


日期:2018/6/13

繪製函數圖


我之前曾經用 Gnuplot 畫函數圖形,但自從學了 Python 以及 matplotlib 之後,就想要用 Python 來畫圖,下圖是 -4π ≤ x ≤ +4π 範圍內對應的 sin(x) 圖形,下方則是程式碼。



"""
 Python筆記: 2D曲線圖
 日期: 2018/6/13
 作者: 王一哲
"""
import numpy as np                                        # 引入科學計算函式庫
import matplotlib.pyplot as plt                           # 引入繪圖函式庫

xmin, xmax, num = -4*np.pi, 4*np.pi, 1000                 # 設定繪圖範圍、取點數
x = np.linspace(xmin, xmax, num)                          # 產生x
y = np.sin(x)                                             # 產生y

plt.figure(figsize = (8, 6), dpi = 100)                   # 設定圖片尺寸
plt.xlabel('x(rad)', fontsize = 16)                       # 設定坐標軸標籤
plt.ylabel('sin(x)', fontsize = 16)
plt.xticks(fontsize = 12)                                 # 設定坐標軸數字格式
plt.yticks(fontsize = 12)
plt.grid(color = 'red', linestyle = '--', linewidth = 1)  # 設定格線顏色、種類、寬度
plt.plot(x, y, color = 'blue', linewidth = 3)             # 繪圖並設定線條顏色、寬度
plt.savefig('plot_2D.svg')                                # 儲存圖片
plt.savefig('plot_2D.png')
plt.show()                                                # 顯示圖片




繪製數據圖


我在之前的文章〈使用for迴圈計算水平抛射資料〉當中,利用 for 迴圈計算相同的水平初速、不同的抛出高度 h 對應的水平射程 R,再將資料存成文字檔。如果想要用 matplotlib
直接作圖,只需要加上一部分的程式碼即可,成果如下圖,下方則是程式碼。雖然這樣做很方便,但是我比較希望學生將資料丟進 SciDAVis 這類的軟體中,順便學習處理數據的方法。


"""
 VPython教學: 5-5.水平抛射, 用for迴圈改變h, 記錄t、R
 Ver. 1: 2018/3/21
 Ver. 2: 2018/6/13  加上用 matplotlib.pyplot 繪圖的部分
 作者: 王一哲
"""
from vpython import *
import matplotlib.pyplot as plt

"""
 1. 參數設定, 設定變數及初始值
"""
size = 1     # 小球半徑
v0 = 5       # 小球水平初速
L = 50       # 地板長度
g = 9.8      # 重力加速度 9.8 m/s^2
dt = 0.001   # 時間間隔
data_h, data_x = [], []     # 儲存繪圖資料的串列

"""
 2. 畫面設定
"""
scene = canvas(title = "Projectile", width = 800, height = 600, x = 0, y = 0, center = vector(0, 5, 0), \
                          background = vector(0, 0.6, 0.6))
floor = box(pos = vector(0, -size, 0), length = L, height = 0.01, width = 10, texture = textures.metal)

# 開啟檔案 data.txt, 屬性為寫入, 先寫入欄位的標題
file = open("data.txt", "w", encoding = "UTF-8")
file.write("h(m), t(s), R(m)\n")

"""
 3. 用for迴圈改變h, 計算t、R, 寫入檔案
"""
for h in range(5, 51, 1):
    t = 0
    ball = sphere(pos = vector(-L/2, h, 0), radius = size, texture = textures.wood, make_trail = True)
    ball.v = vector(v0, 0, 0)
    ball.a = vector(0, -g, 0)
# 物體運動部分
    while(ball.pos.y > floor.height/2):
#        rate(500)
        ball.v += ball.a*dt
        ball.pos += ball.v*dt
        t += dt
    print(h, t, ball.pos.x + L/2)
    file.write(str(h) + "," + str(t) + "," + str(ball.pos.x + L/2) + "\n")
    data_h.append(h)
    data_x.append(ball.pos.x + L/2)

file.close() # 關閉檔案

# 用 matplotlib.pyplot 繪圖
plt.figure(figsize = (8, 6), dpi = 100)                   # 設定圖片尺寸
plt.title('h - R plot', fontsize = 18)                    # 設定圖標題
plt.xlabel('h(m)', fontsize = 16)                         # 設定坐標軸標籤
plt.ylabel('R(m)', fontsize = 16)
plt.xticks(fontsize = 12)                                 # 設定坐標軸數字格式
plt.yticks(fontsize = 12)
plt.grid(color = 'red', linestyle = '--', linewidth = 1)  # 設定格線顏色、種類、寬度
plt.plot(data_h, data_x, marker = 'o', markerfacecolor = 'blue', markersize = 8, color = 'skyblue', linewidth = 3)   # 繪圖並設定線條顏色、寬度
plt.legend(loc='upper right', fontsize = 14)
plt.savefig('h-R_plot.svg')                               # 儲存圖片
plt.savefig('h-R_plot.png')
plt.show()                                                # 顯示圖片


參考資料

  1. https://python-graph-gallery.com/122-multiple-lines-chart/
  2. https://morvanzhou.github.io/tutorials/data-manipulation/plt/

2 則留言:

  1. 回覆
    1. 我是用 matplotlib.font_manager.FontProperties 搭配 Windows 內建的宋體字 simsun.ttc,可以參考以下的程式碼。


      from matplotlib.font_manager import FontProperties
      import matplotlib.pyplot as plt
      import numpy as np

      xmin = -4*np.pi
      xmax = 4*np.pi
      num = 200
      x = np.linspace(xmin, xmax, num)
      y = np.sin(x)

      font = FontProperties(size = '18')
      font_title = FontProperties(fname = r"C:\Windows\Fonts\simsun.ttc", size = '24')

      plt.figure(figsize=(8, 6), dpi=72)

      plt.xlim(xmin,xmax)
      plt.xlabel(r"x", fontproperties = font)
      plt.ylabel(r"sin(x)", fontproperties = font)
      plt.title("正弦函數", fontproperties = font_title)
      plt.grid(True)

      plt.plot(x, y)
      plt.savefig('fig.png')
      plt.show()

      刪除