熱門文章

2019年12月13日 星期五

解決 Linux Mint 上 HackMD 網頁等寬字體問題

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




我在 Linux Mint 19.1 Cinnamon 上使用 Chrome 瀏覧器開啟 HackMD 網站時,程式碼的部分沒有辦法使用等寬字體顯示,這樣很難看清楚縮排的格數,今天剛好遇到一個高手學生幫我解決了這個問題。




無法使用等寬字體顯示程式碼



先在程式碼區段按滑鼠右鍵開啟快速選單,點選最下方的檢查

開啟快速選單


2019年12月12日 星期四

Matplotlib 繪圖技巧:水波干涉動畫

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




前言


以前在維基百科上看到用 MATLAB 繪製的兩個點波源水波干涉動畫,後來我參考網頁上的程式碼,試著用 Scilab 畫出一樣的動畫,甚至把它改成立體圖。但是我現在比較常用 Matplotlib 套件繪圖,也在網路上看過一些用 Matplotlib 繪製的 gif 檔,於是我花了一點時間研究一下繪製動畫的方法。


維基百科兩個點波源水波干涉動畫,圖片來源為 https://en.wikipedia.org/wiki/File:Two_sources_interference.gif




使用 Scilab 自行繪製的水波干涉動畫(2D版)




使用 Scilab 自行繪製的水波干涉動畫(3D版)


2019年12月6日 星期五

SciDAVis 教學 1:XY 散佈圖基本使用方法

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




SciDAVis 的全名為 Scientific Data Analysis and Visualization,照字面的意思可以翻譯為科學資料分析與視覺化工具,用來分析數據、作圖,而且它是一套自由軟體最新的版本為1.25,下載頁面在此(前往下載) 。類似的商業軟體為 OriginSigmaPlot,但是這兩套軟體的售價不便宜,都在萬元以上。雖然用 MicroSoft Excel 和 LibreOffice Calc 也能做到類似的效果,但是 SciDAVis 處理大量數據的效果更好,即使操作界面是沒有中文化,對高中生而言應該還在可接受的範圍內。




SciDAVis

安裝軟體


如果作業系統為 Windows,請選用 scidavis.1.25-win-dist.msi,下載後使用系統管理員身份執行安裝檔,接著不斷地按下一步就完成了。如果作業系統為 Linux,請選用 scidavis-1.25.tar.gz,下載後解壓縮,再依照資料夾中的檔案 "README.installer" 的指示編輯檔案及安裝。安裝完成後執行程式,畫面如下。


SciDAVis 畫面截圖


SciDAVis 教學 2:作圖技巧及化直

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




作圖原則


  1. 假設自變數為$x$、應變數為$y$,先畫出$y-x$關係圖,如果數據點看起來分布在一條斜直線上,利用線性迴歸畫出最接近直線,計算斜率、截距及其不準量;如果數據點看起來是分布在一條曲線上則進行步驟2。
  2. 計算 $\log x$、$\log y$,畫出$\log y - \log x$關係圖,如果數據點看起來分布在一條斜直線上,利用線性迴歸畫出最接近直線,計算斜率、截距及其不準量,其中斜率可以代表$x$、$y$取幾次方時兩者的關係為線性。假設$x$、$y$數學關係為
    $$y^m = kx^n$$
    $$m \log y = \log k + n \log x$$
    $$\log y = \frac{n}{m} \log x + \frac{\log k}{m}$$
    因此$\log y - \log x$關係圖的最接近直線斜率為$n/m$。
  3. 計算 $x^n$、$y^m$,畫出$y^m - x^n$關係圖,如果數據點看起來分布在一條斜直線上,利用線性迴歸畫出最接近直線,計算斜率、截距及其不準量。



自由落下時間與高度關係圖


假設小球原為靜止、離地面高度為$h$、受到重力作用開始落下,只考慮重力的作用,重力加速度$g = 9.8~\mathrm{m/s^2}$,小球在空中飛行時間為$t$、飛行時間不準量為$errt$,實驗數據如下

h(m),t(s),errt(s)
2,0.65,0.01
4,0.89,0.01
6,1.11,0.01
8,1.27,0.01
10,1.42,0.01
12,1.57,0.01
14,1.71,0.01
16,1.79,0.01
18,1.92,0.01
20,2.03,0.01



先畫出$t - h$關係圖,發現數據點應該是分布在一條曲線上,無法進行線性擬合。


t - h 關係圖


2019年12月2日 星期一

Streamplot 範例

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




前言


我為了寫〈均勻帶電圓環的電場〉找到了 matplotlib 官網上關於 streamplot 指令的範例,範例中利用 numpy 的指令直接產生繪圖資料,但是我需要從 csv 檔中讀取由 VPython 產生的資料,因此我需要改寫範例的程式碼。




streamplot 指令範例繪圖成果



2019年12月1日 星期日

均勻帶電圓環的電場

作者:王一哲
日期:2019/12/1




前言


這是一個選修物理上第6章靜電學的題目,但是題目只會問圓心處或是圓心上一段距離處的電場,因為這些位置才能利用對稱性計算電場量值,如果想計算其它位置的電場該怎麼辦?由於我們在 VPython 教學〈靜電力及簡諧〉程式 19-3 已經寫過類似的東西,應該可以從這支程式開始修改。



用 VPython 計算空間中各處的電場


GlowScript 版本
from vpython import *

"""
 1. 參數設定, 設定變數及初始值
"""
Q, R, N = 2E-11, 1, 100  # 帶電圓環總電量, 半徑, 分割數量
q, r = Q/N, 0.01*R       # 分割後小球電量, 半徑
L = 4.1*R                # 畫面寬度
ke = 8.988E9             # 靜電力常數
num = 100                # 將顯示的空間每邊切成 N 等份

"""
 2. 產生帶電球體類別, 回傳帶電球體產生的電場
"""
class Ball:
    def __init__(self, pos, radius, color, charge):
        self.pos = pos
        self.radius = radius
        self.color = color
        self.charge = charge
        self.ball = sphere(pos=self.pos, radius=self.radius, charge=self.charge, color=self.color)
    def electric(self, pos2):
        return ke*self.charge / mag2(pos2-self.pos) * norm(pos2-self.pos)

"""
 3. 畫面設定
"""
# 產生動畫視窗
scene = canvas(title="Electric Field (Circle)", width=600, height=600, x=0, y=0,               
               background=color.black, center=vec(0, 0, 0), range=L)

# 產生帶電圓環上計算電場用的小球
balls = [Ball(pos=vec(R*cos(i*2*pi/N), R*sin(i*2*pi/N), 0), radius=r, color=color.white, charge=q) for i in range(N)]

# 計算畫箭頭的位置
locations = []

# 直線, 儲存資料後用 plot 繪圖
'''
for i in range(num+1):
    locations.append(vec(L/num*i - L/2, 0, 0))
'''
# 平面, 儲存資料後用 streamplot 繪圖
for i in range(num+1):
    for j in range(num+1):
        locations.append(vec(L/num*i - L/2, L/num*j - L/2, 0))

# 立體, 展示用, 但是箭頭太多, 不容易看清楚
'''
for i in range(num+1):
    for j in range(num+1):
        for k in range(num+1):
            locations.append(vec(L/num*i - L/2, L/num*j - L/2, L/num*k - L/2))
'''

# 依序讀取串列 locations 的元素, 在對應的位置產生箭頭
fields = [arrow(pos=location, axis=vec(0, 0, 0), color=color.green) for location in locations]

with open("ElectricFieldCircleData.csv", "w", encoding="UTF-8") as file:
    file.write("x, y, E, Ex, Ey\n")
    
# 更新箭頭的長度及方向, 記錄電場強度最大值, 量值接近最大值偏紅色, 量值接近 0 偏綠色
fmax = 0
for field in fields:
    for ball in balls:
        field.axis += ball.electric(field.pos)
    with open("ElectricFieldCircleData.csv", "a", encoding="UTF-8") as file:
        file.write(str(field.pos.x) + "," + str(field.pos.y) + "," + str(field.axis.mag) + "," + str(field.axis.x) + "," + str(field.axis.y) + "\n")
    if(field.axis.mag >= fmax): fmax = field.axis.mag

for field in fields:
    field.color = vec(field.axis.mag/fmax, 1 - field.axis.mag/fmax, 0)



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倍聲速)