置頂

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

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

熱門文章

2019年11月9日 星期六

Matplotlib 繪圖技巧:繪製選擇題用的函數圖形選項

作者:王一哲
日期:2019/11/9

前言


有時候選擇題會以五張不同的函數圖形作為選項,之前我是用 LibreOffice Draw 的繪圖工具畫好圖形之後再加上選項標籤,最後將五張函數圖形以及選項標籤匯出成一張圖片。下圖是我用 LibreOffice Draw 繪製的選項,題目是要選出自由落下的小球觸地時發生彈性碰撞的v-t圖,但是選項中的曲線畢竟是手動繪製的,只能算是示意圖。如果對於圖形的精準度要求不高,這樣的作法應該可以符合需求,但如果需要畫出精準的函數圖形,LibreOffice Draw 就不太適合了。


使用 LibreOffice Draw 繪製的函數圖形選項



於是我試著改用 NumPy 計算函數值,再用 Matplotlib 中的 subplots 將圖形及標籤一口氣畫好,以下是實際出題的例子。



使用 NumPy + Matplotlib 繪製都卜勒效應題目的選項


試題


假設聲源發出的聲波頻率為 1000 Hz,空氣中的聲速為 340 m/s,下表中是兩種不同狀況下觀察者觀測到的聲波頻率,單位為 Hz。狀況 I:聲源移動速度為 v 接近靜止的觀察者;狀況 II:觀察者移動速度為 v 接近靜止的聲源。下列的 5 張圖形中,請問何者最符合表格中數據?

v (m/s) 0 5 10 15 20 25 30 35 40
狀況 I 測到的聲波頻率 (Hz) 1000.0 1014.9 1030.3 1046.2 1062.5 1079.4 1096.8 1114.8 1133.3
狀況 II 測到的聲波頻率 (Hz) 1000.0 1014.7 1029.4 1044.1 1058.8 1073.5 1088.2 1102.9 1117.6






2019年11月8日 星期五

使用 numpy.genfromtxt 讀取混合格式的資料

作者:王一哲
日期:2019/11/8




之前我測試過使用 numpy.loadtxt 匯入 csv 檔的資料,但是資料的格式都是浮點數 (float),如果資料中某些欄位的資料格式是字串 (string),處理起來相當麻煩,改用 numpy.genfromtxt 會比較簡單。我匯入的資料檔如下:

行星名稱, a (AU), T (yr)
水星, 0.387, 0.241
金星, 0.723, 0.615
地球, 1.000, 1.000
火星, 1.524, 1.881
木星, 5.203, 11.863
土星, 9.555, 29.458
天王星, 19.218, 84.022
海王星, 30.110, 164.774



我用以下程式碼匯入資料並繪製 XY 散布圖。

import numpy as np
import matplotlib.pyplot as plt

# 從 csv 檔讀取資料, 資料以 ',' 分隔, 略過第1列
data = np.genfromtxt("PlanetsData.csv", delimiter=',', dtype=None,
                     names=('Planet', 'a', 'T'), skip_header=1, encoding='UTF-8')
planet, a, T = data['Planet'], data['a'], data['T']

# a - T 關係圖
plt.figure(figsize=(6, 4.5), dpi=100)
plt.title(r'$a - T ~\mathrm{Plot}$', fontsize=16)
plt.xlabel(r'$T ~\mathrm{(yr)}$', fontsize=14)
plt.ylabel(r'$a ~\mathrm{(AU)}$', fontsize=14)
plt.xticks(fontsize=12)
plt.yticks(fontsize=12)
plt.subplots_adjust(left=0.12, bottom=0.15)
plt.grid(color='grey', linestyle='--', linewidth=1)
plt.plot(T, a, color='blue', marker='o', markersize=10, markeredgecolor='black', linestyle='')
plt.show()


2019年11月5日 星期二

克卜勒第三行星運動定律

作者:王一哲
日期:2019/11/4




克卜勒 (Johannes Kepler, December 27, 1571 – November 15, 1630) 提出的行星運動定律共有三條:

1. 第一定律:又稱為軌道定律,繞太陽公轉的行星軌道為橢圓形,太陽位於其中一個焦點上。
2. 第二定律:又稱為等面積速率定律,行星與太陽連線於單位時間內掃過的面積 $\frac{dA}{dt} = \frac{1}{2}rv \sin \theta$
3. 第三定律:又稱為週期定律,繞太陽公轉的行星,其平均軌道半徑,也就是橢圓軌道的半長軸 $a$,與公轉週期$T$的關係為$\frac{a^3}{T^2}=定值$

現行的高中物理教材中,只有提到第三定律的數學式子,我們可以讓學生用現代的觀測資料,試著驗證第三定律。




太陽系八大行星


從網路上可以找到行星公轉軌道的資料,為了簡化數值,半長軸$a$的單位為天文單位 (astronomical units, AU),公轉週期的單位為地球年 (yr)。

行星 公轉週期T (yr) 半長軸 a (AU)
水星 0.241 0.387
金星 0.615 0.723
地球 1.000 1.000
火星 1.881 1.524
木星 11.862 5.203
土星 29.458 9.555
天王星 84.022 19.218
海王星 164.774 30.110



我們先試著畫出 $a - T$ 關係圖,基本上看不出兩者的數學關係。




2019年10月26日 星期六

都卜勒效應及震波示意圖

作者:王一哲
日期:2019/10/25

本次課程檔案已上傳至 GeoGebraTube,可以線上操作或下載檔案。


原理


假設波源發出的聲波頻率為 $f_0$,空氣中的聲速為 $v$,波源以速度 $v_S$ 接近靜止的觀察者時,由於聲波的波長被壓縮,但空氣中的聲速不變,因此觀測到的聲波頻率會變為

$$f = \frac{v}{v-v_S} f_0$$

若波源以速度 $v_S$ 遠離靜止的觀察者時,由於聲波的波長被拉長,但空氣中的聲速不變,因此觀測到的聲波頻率會變為

$$f = \frac{v}{v+v_S} f_0$$


都卜勒效應示意圖動畫 (波源移動速度為0.6倍聲速)


2019年8月14日 星期三

一維彈性碰撞次數與圓周率

作者:王一哲
日期:2019/8/14




前言


如下圖所示,假設在水平光滑桌面上有兩個木塊,右側紅色木塊的質量為$m_1$、初速度方向向左,左側綠色木塊的質量為$m_2$、原為靜止,且$m_1 = 100^n m_2$,最左側有固定的牆壁。若木塊之間、木塊與牆壁之間的碰撞皆為一維彈性碰撞,則碰撞次數與$n$的關係如下。


裝置示意圖



n 碰撞次數
1 31
2 314
3 3141
4 31415
5 314159



如果想要了解背後的原理請看這部影片 So why do colliding blocks compute pi? [1],影片作者是3Blue1Brown。接下來我們拿之前寫過的〈一維彈性碰撞〉程式碼來修改,試著畫出這個現象。


2019年8月13日 星期二

使用 Python 產生聲音及繪製頻譜圖

作者:王一哲
日期:2019/8/13




前言


我在去年看到了啾啾鞋講解電話按鍵聲的影片 [1],裡面用到的技術稱為雙音多頻訊號 (Dual-Tone Multi-Frequency, DTMF) [2],各個按鍵對應的聲音頻率如下表所示

1209 Hz 1336 Hz 1477 Hz 1633 Hz
697 Hz 1 2 3 A
770 Hz 4 5 6 B
852 Hz 7 8 9 C
941 Hz * 0 # D



另外也在 YouTube 上找到了成功大學數學系舒宇宸教授演講的影片 [3],教授在演講時用 MATLAB 產生了上述表格中的聲音。既然用 MATLAB 可以做到,應該也可以用 Python 做到同樣的效果才對,於是我花了一天的時間研究了一下,找到以下的解決方案。



2019年8月8日 星期四

使用 numpy.genfromtxt 從文字檔中讀取資料

作者:王一哲
日期:2019/8/8




假設某人儲存資料時不是用csv檔,而是使用數量不一致的空格分格資料,我們將前一篇文章〈最接近直線〉的數據排列成底下這樣再儲存為文字檔data.txt。

index   x  errx   y     erry
    0   1.0  0.1      4.9   0.5
 1  2.0   0.1    6.9  0.5
2   3.0  0.1     9.0      0.5
  3   4.0    0.1  11.1   0.6
   4  5.0   0.1  13.2   0.6
 5  6.0   0.2    15.2     0.8
6 7.0 0.2  16.9    0.8
  7  8.0  0.2     18.9      0.8
 8    9.0   0.2  20.9   0.8
9   10.0  0.2   22.8    0.8

我絕對不會用這樣的格式儲存資料,但如果真的遇到這種狀況還是有辦法解決,只要使用numpy.genfromtxt即可,語法為

2019年8月6日 星期二

最接近直線

作者:王一哲
日期:2019/8/5

前言


物理科及化學科在處理實驗數據時,通常會先繪製 XY 散佈圖,如果資料點看起來有線性的關係,就要用最小平方法計算最接近直線的斜率和截距,再試著解釋斜率和截距的物理意義。但如果更講究一點,由於測量數據時本身就會有一定的不準量,最接近直線的斜率、截距也會有不準量,要用什麼方法才能很方便地算出這些數呢?



最接近直線公式


以下的公式是我從物理奧林匹亞培訓講義上抄來的。假設操縱變因(自變數)為$x$、不準量為$\Delta x$,測量的應變變因(應變數)為$y$、不準量為$\Delta y$,數據共有$n$組。則最接近直線

$$斜率 \quad a = \frac{\sum x \sum y - n \sum xy}{(\sum x)^2 - n \sum x^2}$$
$$截距 \quad b = \frac{\sum x \sum xy - \sum y \sum x^2}{(\sum x)^2 - n \sum x^2}$$
$$相關係數 \quad R = \frac{\sum x \sum y - n \sum xy}{\sqrt{\left[ (\sum x)^2 - n \sum x^2 \right] \left[ (\sum y)^2 - n \sum y^2 \right]}}$$

為了要計算斜率及截距的不準量,我們先定義下列的符號

$$\sigma_x = \sqrt{\frac{\sum (\Delta x)^2}{n}}$$
$$\sigma_y = \sqrt{\frac{\sum (\Delta y)^2}{n}}$$
$$\sigma = \sqrt{\sigma_y^2 + a^2 \sigma_x^2}$$

斜率與截距的不準量分別為

$$斜率的不準量 \quad \Delta a = \sqrt{\frac{n \sigma^2}{n \sum x^2 - (\sum x)^2}}$$
$$截距的不準量 \quad \Delta b = \sqrt{\frac{\sigma^2 \sum x^2}{n \sum x^2 - (\sum x)^2}}$$

如果要將$x$軸的不準量$\Delta x$加到$y$軸上,等效的$y$軸不準量計算方式為

$$\Delta y_{eff} = \sqrt{(\Delta x)^2 + (a \Delta y)^2}$$



2019年7月22日 星期一

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

作者:王一哲
日期:2019/7/22

前言


以下是將在四張小圖畫在同一張圖中的作法,將圖排列為 $2 \times 2$ 的樣子,圖中的函數分別為

$$\mathrm{sigmoid:}~~~~~S(x) = \frac{1}{1+e^{-x}}$$
$$\mathrm{tanh:}~~~~~\tanh(x) = \frac{e^x - e^{-x}}{e^x + e^{-x}}$$
$$\mathrm{ReLU:}~~~~~f(x) = \begin{cases} 0 & \mathrm{if~~~} x < 0 \\ x & \mathrm{otherwise} \end{cases}$$ $$\mathrm{Leaky~ReLU:}f(x) = \begin{cases} \lambda x & \mathrm{if~~~} x < 0 \\ x & \mathrm{otherwise} \end{cases}$$


2019年7月21日 星期日

於 Matplotlib 繪製的圖表中插入 LaTeX 數學式

作者:王一哲
日期:2019/7/21

前言


如果想在 Matplotlib 繪製的圖形中插入簡單的 $\LaTeX$ 數學式,例如

$$f(x) = ax^2 + bx + c$$

只需要在繪圖時加入
label=r'$f(x) = ax^2 + bx + c$'

即可。但如果要插入更複雜的數學式,例如

$$f(x) =
\begin{cases}
0.2x & \mathrm{if~~~} x < 0 \\ x & \mathrm{otherwise} \end{cases}$$ 會需要另外安裝 $\LaTeX$ 軟體,還需要另外加上一些程式碼。