This commit is contained in:
2026-02-02 23:47:51 +08:00
parent 244e157bc0
commit 83cb8809a2
14 changed files with 229 additions and 101 deletions

View File

@@ -103,43 +103,49 @@ def main():
print(f"K / Physical limit = {K_fixed/physical_max:.2f}x")
# ========== Create Visualization ==========
fig, ax = plt.subplots(figsize=(12, 7))
# 缩小图片尺寸(比例不变),使字体相对更大
fig, ax = plt.subplots(figsize=(8, 4.67))
# 中低饱和度配色
color_data = '#5D6D7E' # 灰蓝色 - 数据点
color_curve = '#52796F' # 暗绿色 - S曲线
color_target = '#7B9EA8' # 灰蓝绿色 - 2050标记
# Historical data points
ax.scatter(years, launches, color='#2C3E50', s=100, alpha=0.9,
ax.scatter(years, launches, color=color_data, s=80, alpha=0.85,
label='Historical Data (2010-2025)', zorder=4, edgecolor='white', linewidth=1)
# Generate smooth S-curve
years_smooth = np.linspace(start_year, 2080, 500)
years_smooth = np.linspace(start_year, 2055, 500)
t_smooth = years_smooth - start_year
pred_smooth = richards(t_smooth, K_fixed, r, t0, v)
# S-curve prediction
ax.plot(years_smooth, pred_smooth, color='#27AE60', lw=3,
ax.plot(years_smooth, pred_smooth, color=color_curve, lw=2.5,
label=f'Richards Model (K={K_fixed}, R²={r_squared:.3f})', zorder=2)
# K=4298 saturation line
ax.axhline(K_fixed, color='#27AE60', ls=':', lw=2, alpha=0.7,
ax.axhline(K_fixed, color=color_curve, ls=':', lw=1.5, alpha=0.6,
label=f'K = {K_fixed}')
# Mark 2050 line only
ax.axvline(2050, color='#3498DB', ls=':', lw=2, alpha=0.8)
ax.text(2051, K_fixed*0.85, '2050\n(Target)', fontsize=10, color='#3498DB')
ax.axvline(2050, color=color_target, ls=':', lw=1.5, alpha=0.7)
ax.text(2050.5, K_fixed*0.83, '2050\n(Target)', fontsize=9, color=color_target)
# Only show 2050 prediction point
t_2050 = 2050 - start_year
pred_2050 = richards(t_2050, K_fixed, r, t0, v)
ax.scatter([2050], [pred_2050], color='#3498DB', s=80, marker='D', zorder=4)
ax.scatter([2050], [pred_2050], color=color_target, s=60, marker='D', zorder=4)
ax.annotate(f'{pred_2050:.0f}', xy=(2050, pred_2050),
xytext=(2051, pred_2050+150),
fontsize=9, color='#3498DB', fontweight='bold')
xytext=(2050.5, pred_2050+180),
fontsize=9, color=color_target, fontweight='bold')
# Formatting
ax.set_xlabel('Year', fontsize=12)
ax.set_ylabel('Annual Launches', fontsize=12)
ax.legend(loc='upper left', fontsize=10)
ax.grid(True, alpha=0.3)
ax.set_xlim(2008, 2080)
ax.set_xlabel('Year', fontsize=11)
ax.set_ylabel('Annual Launches', fontsize=11)
ax.legend(loc='upper left', fontsize=9)
ax.grid(True, alpha=0.25)
ax.set_xlim(2010, 2055)
ax.set_ylim(0, K_fixed * 1.15)
plt.tight_layout()