fork download
  1. import matplotlib.pyplot as plt
  2. import numpy as np
  3.  
  4. # 設定中文字型與風格 (使用內建字型以確保顯示)
  5. plt.rcParams['font.sans-serif'] = ['Taipei Sans TC Beta', 'Microsoft JhengHei', 'SimHei', 'Arial']
  6. plt.rcParams['axes.unicode_minus'] = False
  7. plt.style.use('seaborn-v0_8-whitegrid')
  8.  
  9. # 模擬參數
  10. np.random.seed(101) # 固定種子以求結果一致
  11. n_simulations = 5000
  12. mu = 0.075 # 7.5%
  13. sigma = 0.16 # 16%
  14. initial_principal = 100
  15. contribution_amount = 80
  16.  
  17. def run_simulation(years, contributions):
  18. sim_paths = np.zeros((n_simulations, years + 1))
  19. sim_paths[:, 0] = initial_principal
  20. cost_line = np.zeros(years + 1)
  21. cost_line[0] = initial_principal
  22.  
  23. for t in range(1, years + 1):
  24. shock = np.random.normal(0, 1, n_simulations)
  25. returns = np.exp((mu - 0.5 * sigma**2) + sigma * shock)
  26. sim_paths[:, t] = sim_paths[:, t-1] * returns
  27. cost_line[t] = cost_line[t-1]
  28.  
  29. if t in contributions:
  30. sim_paths[:, t] += contribution_amount
  31. cost_line[t] += contribution_amount
  32. return sim_paths, cost_line
  33.  
  34. def plot_chart(years, contributions, title, filename):
  35. sim_paths, cost_line = run_simulation(years, contributions)
  36.  
  37. p10 = np.percentile(sim_paths, 10, axis=0)
  38. p50 = np.percentile(sim_paths, 50, axis=0)
  39. p90 = np.percentile(sim_paths, 90, axis=0)
  40.  
  41. # 設定高解析度畫布
  42. fig, ax = plt.subplots(figsize=(12, 7), dpi=300)
  43.  
  44. x = np.arange(0, years + 1)
  45.  
  46. # 繪製區域
  47. ax.fill_between(x, p10, p90, color='#87CEEB', alpha=0.4, label='80% 機率分佈 (P10-P90)')
  48.  
  49. # 繪製線條
  50. ax.plot(x, p50, color='#00008B', linewidth=3, label='中位數 (P50) - 最可能的結果')
  51. ax.step(x, cost_line, color='#DC143C', linestyle='--', linewidth=2.5, where='post', label='投入本金 (成本)')
  52.  
  53. # 標示數值
  54. ax.text(years, p90[-1], f' P90 (樂觀): {int(p90[-1])}', fontsize=12, color='#00008B', fontweight='bold', va='center')
  55. ax.text(years, p50[-1], f' P50 (中位): {int(p50[-1])}', fontsize=12, color='#00008B', fontweight='bold', va='center')
  56. ax.text(years, p10[-1], f' P10 (悲觀): {int(p10[-1])}', fontsize=12, color='#00008B', fontweight='bold', va='top')
  57. ax.text(years, cost_line[-1], f' 總成本: {int(cost_line[-1])}', fontsize=12, color='#DC143C', fontweight='bold', va='top')
  58.  
  59. # 標題與標籤
  60. ax.set_title(title, fontsize=18, fontweight='bold', pad=20)
  61. ax.set_xlabel('年份 (Year)', fontsize=14)
  62. ax.set_ylabel('資產金額 (Value)', fontsize=14)
  63. ax.set_xlim(0, years + 1)
  64. ax.grid(True, linestyle='--', alpha=0.6)
  65. ax.legend(loc='upper left', fontsize=12, frameon=True, facecolor='white', framealpha=0.9)
  66.  
  67. plt.tight_layout()
  68. plt.show()
  69.  
  70. # 執行繪圖
  71. plot_chart(10, [1, 4, 7], "情境一:10年期 (第1,4,7年加碼)", "chart1")
  72. plot_chart(13, [1, 4, 7, 10], "情境二:13年期 (第1,4,7,10年加碼)", "chart2")
  73. plot_chart(16, [1, 4, 7, 10, 13], "情境三:16年期 (第1,4,7,10,13年加碼)", "chart3")
  74.  
Success #stdin #stdout #stderr 3.67s 159492KB
stdin
Standard input is empty
stdout
Standard output is empty
stderr
Fontconfig error: No writable cache directories
./prog.py:67: UserWarning: Glyph 24180 (\N{CJK UNIFIED IDEOGRAPH-5E74}) missing from font(s) DejaVu Sans.
./prog.py:67: UserWarning: Glyph 20221 (\N{CJK UNIFIED IDEOGRAPH-4EFD}) missing from font(s) DejaVu Sans.
./prog.py:67: UserWarning: Glyph 36039 (\N{CJK UNIFIED IDEOGRAPH-8CC7}) missing from font(s) DejaVu Sans.
./prog.py:67: UserWarning: Glyph 29986 (\N{CJK UNIFIED IDEOGRAPH-7522}) missing from font(s) DejaVu Sans.
./prog.py:67: UserWarning: Glyph 37329 (\N{CJK UNIFIED IDEOGRAPH-91D1}) missing from font(s) DejaVu Sans.
./prog.py:67: UserWarning: Glyph 38989 (\N{CJK UNIFIED IDEOGRAPH-984D}) missing from font(s) DejaVu Sans.
./prog.py:67: UserWarning: Glyph 24773 (\N{CJK UNIFIED IDEOGRAPH-60C5}) missing from font(s) DejaVu Sans.
./prog.py:67: UserWarning: Glyph 22659 (\N{CJK UNIFIED IDEOGRAPH-5883}) missing from font(s) DejaVu Sans.
./prog.py:67: UserWarning: Glyph 19968 (\N{CJK UNIFIED IDEOGRAPH-4E00}) missing from font(s) DejaVu Sans.
./prog.py:67: UserWarning: Glyph 65306 (\N{FULLWIDTH COLON}) missing from font(s) DejaVu Sans.
./prog.py:67: UserWarning: Glyph 26399 (\N{CJK UNIFIED IDEOGRAPH-671F}) missing from font(s) DejaVu Sans.
./prog.py:67: UserWarning: Glyph 31532 (\N{CJK UNIFIED IDEOGRAPH-7B2C}) missing from font(s) DejaVu Sans.
./prog.py:67: UserWarning: Glyph 21152 (\N{CJK UNIFIED IDEOGRAPH-52A0}) missing from font(s) DejaVu Sans.
./prog.py:67: UserWarning: Glyph 30908 (\N{CJK UNIFIED IDEOGRAPH-78BC}) missing from font(s) DejaVu Sans.
./prog.py:67: UserWarning: Glyph 27138 (\N{CJK UNIFIED IDEOGRAPH-6A02}) missing from font(s) DejaVu Sans.
./prog.py:67: UserWarning: Glyph 35264 (\N{CJK UNIFIED IDEOGRAPH-89C0}) missing from font(s) DejaVu Sans.
./prog.py:67: UserWarning: Glyph 20013 (\N{CJK UNIFIED IDEOGRAPH-4E2D}) missing from font(s) DejaVu Sans.
./prog.py:67: UserWarning: Glyph 20301 (\N{CJK UNIFIED IDEOGRAPH-4F4D}) missing from font(s) DejaVu Sans.
./prog.py:67: UserWarning: Glyph 24754 (\N{CJK UNIFIED IDEOGRAPH-60B2}) missing from font(s) DejaVu Sans.
./prog.py:67: UserWarning: Glyph 32317 (\N{CJK UNIFIED IDEOGRAPH-7E3D}) missing from font(s) DejaVu Sans.
./prog.py:67: UserWarning: Glyph 25104 (\N{CJK UNIFIED IDEOGRAPH-6210}) missing from font(s) DejaVu Sans.
./prog.py:67: UserWarning: Glyph 26412 (\N{CJK UNIFIED IDEOGRAPH-672C}) missing from font(s) DejaVu Sans.
./prog.py:67: UserWarning: Glyph 27231 (\N{CJK UNIFIED IDEOGRAPH-6A5F}) missing from font(s) DejaVu Sans.
./prog.py:67: UserWarning: Glyph 29575 (\N{CJK UNIFIED IDEOGRAPH-7387}) missing from font(s) DejaVu Sans.
./prog.py:67: UserWarning: Glyph 20998 (\N{CJK UNIFIED IDEOGRAPH-5206}) missing from font(s) DejaVu Sans.
./prog.py:67: UserWarning: Glyph 20296 (\N{CJK UNIFIED IDEOGRAPH-4F48}) missing from font(s) DejaVu Sans.
./prog.py:67: UserWarning: Glyph 25976 (\N{CJK UNIFIED IDEOGRAPH-6578}) missing from font(s) DejaVu Sans.
./prog.py:67: UserWarning: Glyph 26368 (\N{CJK UNIFIED IDEOGRAPH-6700}) missing from font(s) DejaVu Sans.
./prog.py:67: UserWarning: Glyph 21487 (\N{CJK UNIFIED IDEOGRAPH-53EF}) missing from font(s) DejaVu Sans.
./prog.py:67: UserWarning: Glyph 33021 (\N{CJK UNIFIED IDEOGRAPH-80FD}) missing from font(s) DejaVu Sans.
./prog.py:67: UserWarning: Glyph 30340 (\N{CJK UNIFIED IDEOGRAPH-7684}) missing from font(s) DejaVu Sans.
./prog.py:67: UserWarning: Glyph 32080 (\N{CJK UNIFIED IDEOGRAPH-7D50}) missing from font(s) DejaVu Sans.
./prog.py:67: UserWarning: Glyph 26524 (\N{CJK UNIFIED IDEOGRAPH-679C}) missing from font(s) DejaVu Sans.
./prog.py:67: UserWarning: Glyph 25237 (\N{CJK UNIFIED IDEOGRAPH-6295}) missing from font(s) DejaVu Sans.
./prog.py:67: UserWarning: Glyph 20837 (\N{CJK UNIFIED IDEOGRAPH-5165}) missing from font(s) DejaVu Sans.
./prog.py:67: UserWarning: Glyph 20108 (\N{CJK UNIFIED IDEOGRAPH-4E8C}) missing from font(s) DejaVu Sans.
./prog.py:67: UserWarning: Glyph 19977 (\N{CJK UNIFIED IDEOGRAPH-4E09}) missing from font(s) DejaVu Sans.