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

@@ -585,6 +585,96 @@ def plot_sensitivity_analysis(
return fig
def plot_tornado_chart_standalone(
payload_df: pd.DataFrame,
elevator_df: pd.DataFrame,
frequency_df: pd.DataFrame,
alpha_df: pd.DataFrame,
save_path: str = '/Volumes/Files/code/mm/20260130_b/p1/tornado_chart.png'
):
"""
单独绘制 Tornado Chart敏感性汇总图
- XY轴反转垂直柱状图
- 长宽比 0.618
- 无标题
- 有图例
- 低饱和度色系
"""
# 使用0.618黄金比例
fig_width = 8
fig_height = fig_width * 0.618
fig, ax = plt.subplots(figsize=(fig_width, fig_height))
# 计算敏感性指标
baseline_T = 139
sensitivities = [
('Payload\n(100→150t)',
(payload_df['optimal_T_lambda504'].iloc[0] - baseline_T) / baseline_T * 100,
(payload_df['optimal_T_lambda504'].iloc[-1] - baseline_T) / baseline_T * 100),
('Elevator Cap.\n(80%→120%)',
(elevator_df['optimal_T_lambda504'].iloc[0] - baseline_T) / baseline_T * 100,
(elevator_df['optimal_T_lambda504'].iloc[-1] - baseline_T) / baseline_T * 100),
('Launch Freq.\n(0.5→2/day)',
(frequency_df['optimal_T_lambda504'].iloc[0] - baseline_T) / baseline_T * 100,
(frequency_df['optimal_T_lambda504'].iloc[-1] - baseline_T) / baseline_T * 100),
('Struct. Coef.\n(0.06→0.14)',
(alpha_df['optimal_T_lambda504'].iloc[0] - baseline_T) / baseline_T * 100,
(alpha_df['optimal_T_lambda504'].iloc[-1] - baseline_T) / baseline_T * 100),
]
# 低饱和度配色
color_positive = '#7A9CBF' # 灰蓝色参数增加导致T*增加)
color_negative = '#C4816B' # 灰橙红色参数增加导致T*减少)
x_pos = np.arange(len(sensitivities))
bar_width = 0.6
# 绘制柱状图XY反转使用垂直柱状图
for i, (name, low, high) in enumerate(sensitivities):
bar_color = color_positive if high > low else color_negative
bar_height = high - low
bar_bottom = min(low, high)
ax.bar(i, bar_height, bottom=bar_bottom, width=bar_width,
color=bar_color, alpha=0.8, edgecolor='#555555', linewidth=0.8)
# 标记端点
ax.plot(i, low, 'o', color='#444444', markersize=7, zorder=5)
ax.plot(i, high, '^', color='#444444', markersize=7, zorder=5)
ax.plot([i, i], [low, high], '-', color='#444444', linewidth=1.5, zorder=4)
# 基准线
ax.axhline(y=0, color='#333333', linestyle='-', linewidth=1.2)
# 设置轴
ax.set_xticks(x_pos)
ax.set_xticklabels([s[0] for s in sensitivities], fontsize=10)
ax.set_ylabel('Change in Optimal Timeline T* (%)', fontsize=11)
ax.grid(True, alpha=0.3, axis='y')
# 添加图例
from matplotlib.patches import Patch
from matplotlib.lines import Line2D
legend_elements = [
Patch(facecolor=color_negative, edgecolor='#555555', alpha=0.8,
label='Parameter ↑ → T* ↓'),
Patch(facecolor=color_positive, edgecolor='#555555', alpha=0.8,
label='Parameter ↑ → T* ↑'),
Line2D([0], [0], marker='o', color='#444444', linestyle='None',
markersize=6, label='Low value'),
Line2D([0], [0], marker='^', color='#444444', linestyle='None',
markersize=6, label='High value'),
]
ax.legend(handles=legend_elements, loc='upper right', fontsize=9, framealpha=0.9)
plt.tight_layout()
plt.savefig(save_path, dpi=150, bbox_inches='tight')
print(f"Tornado chart saved to: {save_path}")
return fig
def plot_tradeoff_comparison(
save_path: str = '/Volumes/Files/code/mm/20260130_b/p1/sensitivity_tradeoff.png'
):