cwadayi commited on
Commit
576e90d
·
verified ·
1 Parent(s): 4a31c97

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +22 -51
app.py CHANGED
@@ -2,90 +2,61 @@ import gradio as gr
2
  import numpy as np
3
  import matplotlib.pyplot as plt
4
 
5
- # 解決 Matplotlib 中文亂碼問題 (關鍵修正)
6
- # 指定使用 Noto Sans CJK TC 字體,這是我們透過 packages.txt 安裝的
7
- plt.rcParams['font.sans-serif'] = ['Noto Sans CJK TC', 'sans-serif']
8
- # 正常顯示負號,以防未來有需要
9
- plt.rcParams['axes.unicode_minus'] = False
10
-
11
  # --- 核心計算與繪圖函數 ---
12
  def plot_seismic_refraction(v1, v2, h, x_max):
13
  """
14
  根據輸入的地層參數,計算並繪製折射震測的走時曲線。
15
-
16
- 參數:
17
- v1 (float): 第一層介質速度 (m/s)
18
- v2 (float): 第二層介質速度 (m/s)
19
- h (float): 第一層介質厚度 (m)
20
- x_max (float): 模擬的最大測線距離 (m)
21
-
22
- 返回:
23
- matplotlib.figure: 走時曲線圖
24
- str: 包含計算結果的 Markdown 格式化文字
25
  """
26
  # 物理條件檢查:折射必須 V2 > V1
27
  if v2 <= v1:
28
- # 建立一個空的圖表並顯示錯誤訊息
29
  fig, ax = plt.subplots(figsize=(10, 6))
30
- ax.text(0.5, 0.5, '錯誤:V2 必須大於 V1 才能產生臨界折射!\n(Error: V2 must be greater than V1 for critical refraction to occur.)',
31
  ha='center', va='center', fontsize=12, color='red')
32
- ax.set_xlabel("與震源的距離 (Distance, m)")
33
- ax.set_ylabel("傳播時間 (Travel Time, s)")
34
  ax.grid(True)
35
- ax.set_title("走時曲線 (Travel-Time Curve)")
36
  return fig, "### 參數錯誤\n請確保第二層速度 (V2) 大於第一層速度 (V1)。"
37
 
38
  # 1. 計算關鍵物理量
39
- # 臨界角 (radians and degrees)
40
  theta_c_rad = np.arcsin(v1 / v2)
41
  theta_c_deg = np.rad2deg(theta_c_rad)
42
-
43
- # 截時 (Intercept Time, ti)
44
  ti = (2 * h * np.cos(theta_c_rad)) / v1
45
-
46
- # 交越距離 (Crossover Distance, xc)
47
  xc = 2 * h * np.sqrt((v2 + v1) / (v2 - v1))
48
 
49
  # 2. 準備繪圖數據
50
  x = np.linspace(0, x_max, 500)
51
-
52
- # 直達波走時 (Direct Wave)
53
  t_direct = x / v1
54
-
55
- # 折射波走時 (Refracted Wave)
56
  t_refracted = (x / v2) + ti
57
-
58
- # 實際的初達波 (First Arrival)
59
  t_first_arrival = np.minimum(t_direct, t_refracted)
60
 
61
- # 3. 使用 Matplotlib 繪圖
62
  fig, ax = plt.subplots(figsize=(10, 6))
63
 
64
- # 繪製各波線
65
- ax.plot(x, t_direct, 'b--', label=f'直達波 (Direct Wave) - 斜率 1/{v1:.0f}')
66
- ax.plot(x, t_refracted, 'g--', label=f'折射波 (Refracted Wave) - 斜率 1/{v2:.0f}')
67
- ax.plot(x, t_first_arrival, 'r-', linewidth=3, label='初達波 (First Arrival)')
68
 
69
- # 標示交越距離
70
  if xc < x_max:
71
- ax.axvline(x=xc, color='k', linestyle=':', label=f'交越距離 (Crossover) = {xc:.1f} m')
72
- ax.plot(xc, xc/v1, 'ko') # 標示交越點
73
 
74
- # 標示截時
75
- ax.plot(0, ti, 'mo', markersize=8, label=f'截時 (Intercept) = {ti*1000:.1f} ms')
76
 
77
- # 設定圖表樣式
78
- ax.set_title("互動式震測折射走時圖", fontsize=16)
79
- ax.set_xlabel("與震源的距離 (Distance, m)", fontsize=12)
80
- ax.set_ylabel("傳播時間 (Travel Time, s)", fontsize=12)
 
81
  ax.legend()
82
  ax.grid(True)
83
  ax.set_xlim(0, x_max)
84
  ax.set_ylim(0, max(t_direct) * 1.1)
85
-
86
  plt.tight_layout()
87
 
88
- # 4. 準備輸出的說明文字 (Markdown 格式)
89
  results_md = f"""
90
  ### 🔬 分析結果
91
 
@@ -109,7 +80,7 @@ def plot_seismic_refraction(v1, v2, h, x_max):
109
 
110
  return fig, results_md
111
 
112
- # --- Gradio 介面設定 ---
113
  with gr.Blocks(theme=gr.themes.Soft()) as demo:
114
  gr.Markdown("# 地心震波奇幻之旅:互動折射震測實驗室 🌍")
115
  gr.Markdown(
@@ -149,8 +120,8 @@ with gr.Blocks(theme=gr.themes.Soft()) as demo:
149
  ---
150
  ### 學習重點
151
  1. **觀察斜率**: 直達波的斜率是 `1/V1`,折射波的斜率是 `1/V2`。試著調整 `V1` 和 `V2`,看看線條的陡峭程度如何變化?(速度越快,線越陡,斜率越小)。
152
- 2. **觀察截時 (Intercept Time)**: 試著只增加厚度 `h`,看看綠色虛線在 Y 軸上的截距有什麼變化?(厚度越厚,截時越大)。
153
- 3. **觀察交越距離 (Crossover Distance)**: 試著增加 `h` 或減小 `V2` 與 `V1` 的速度差,看看紅線與藍線的交叉點 (黑色垂直虛線) 如何向右移動?
154
  4. **必要條件**: 試著將 `V2` 調整到比 `V1` 小,看看會發生什麼事?你會發現,臨界折射的現象消失了!
155
 
156
  <footer>
 
2
  import numpy as np
3
  import matplotlib.pyplot as plt
4
 
 
 
 
 
 
 
5
  # --- 核心計算與繪圖函數 ---
6
  def plot_seismic_refraction(v1, v2, h, x_max):
7
  """
8
  根據輸入的地層參數,計算並繪製折射震測的走時曲線。
9
+ 圖表內的標籤已改為英文。
 
 
 
 
 
 
 
 
 
10
  """
11
  # 物理條件檢查:折射必須 V2 > V1
12
  if v2 <= v1:
 
13
  fig, ax = plt.subplots(figsize=(10, 6))
14
+ ax.text(0.5, 0.5, 'Error: V2 must be greater than V1 for critical refraction to occur.',
15
  ha='center', va='center', fontsize=12, color='red')
16
+ ax.set_xlabel("Distance (m)")
17
+ ax.set_ylabel("Travel Time (s)")
18
  ax.grid(True)
19
+ ax.set_title("Travel-Time Curve")
20
  return fig, "### 參數錯誤\n請確保第二層速度 (V2) 大於第一層速度 (V1)。"
21
 
22
  # 1. 計算關鍵物理量
 
23
  theta_c_rad = np.arcsin(v1 / v2)
24
  theta_c_deg = np.rad2deg(theta_c_rad)
 
 
25
  ti = (2 * h * np.cos(theta_c_rad)) / v1
 
 
26
  xc = 2 * h * np.sqrt((v2 + v1) / (v2 - v1))
27
 
28
  # 2. 準備繪圖數據
29
  x = np.linspace(0, x_max, 500)
 
 
30
  t_direct = x / v1
 
 
31
  t_refracted = (x / v2) + ti
 
 
32
  t_first_arrival = np.minimum(t_direct, t_refracted)
33
 
34
+ # 3. 使用 Matplotlib 繪圖 (標籤已改為英文)
35
  fig, ax = plt.subplots(figsize=(10, 6))
36
 
37
+ # --- 英文圖例標籤修改處 ---
38
+ ax.plot(x, t_direct, 'b--', label=f'Direct Wave (Slope 1/{v1:.0f})')
39
+ ax.plot(x, t_refracted, 'g--', label=f'Refracted Wave (Slope 1/{v2:.0f})')
40
+ ax.plot(x, t_first_arrival, 'r-', linewidth=3, label='First Arrival')
41
 
 
42
  if xc < x_max:
43
+ ax.axvline(x=xc, color='k', linestyle=':', label=f'Crossover Distance = {xc:.1f} m')
44
+ ax.plot(xc, xc/v1, 'ko')
45
 
46
+ ax.plot(0, ti, 'mo', markersize=8, label=f'Intercept Time = {ti*1000:.1f} ms')
 
47
 
48
+ # --- 英文圖表/座標軸標題修改處 ---
49
+ ax.set_title("Interactive Seismic Refraction T-X Plot", fontsize=16)
50
+ ax.set_xlabel("Distance (m)", fontsize=12)
51
+ ax.set_ylabel("Travel Time (s)", fontsize=12)
52
+
53
  ax.legend()
54
  ax.grid(True)
55
  ax.set_xlim(0, x_max)
56
  ax.set_ylim(0, max(t_direct) * 1.1)
 
57
  plt.tight_layout()
58
 
59
+ # 4. 準備輸出的說明文字 (這部分維持中文)
60
  results_md = f"""
61
  ### 🔬 分析結果
62
 
 
80
 
81
  return fig, results_md
82
 
83
+ # --- Gradio 介面設定 (這部分維持中文) ---
84
  with gr.Blocks(theme=gr.themes.Soft()) as demo:
85
  gr.Markdown("# 地心震波奇幻之旅:互動折射震測實驗室 🌍")
86
  gr.Markdown(
 
120
  ---
121
  ### 學習重點
122
  1. **觀察斜率**: 直達波的斜率是 `1/V1`,折射波的斜率是 `1/V2`。試著調整 `V1` 和 `V2`,看看線條的陡峭程度如何變化?(速度越快,線越陡,斜率越小)。
123
+ 2. **觀察截時 (Intercept Time)**: 試著只增加厚度 `h`,看看 Y 軸上的截距有什麼變化?(厚度越厚,截時越大)。
124
+ 3. **觀察交越距離 (Crossover Distance)**: 試著增加 `h` 或減小 `V2` 與 `V1` 的速度差,看看交叉點如何向右移動?
125
  4. **必要條件**: 試著將 `V2` 調整到比 `V1` 小,看看會發生什麼事?你會發現,臨界折射的現象消失了!
126
 
127
  <footer>