plane: fig

This commit is contained in:
2026-02-02 21:47:52 +08:00
parent 8192fcc354
commit 244e157bc0
11 changed files with 3245 additions and 3108 deletions

Binary file not shown.

Binary file not shown.

View File

@@ -556,6 +556,143 @@ def plot_comprehensive_summary(data, save_path='aviation_cost_summary.png'):
return fig
# ============== 图表6: 燃油占比趋势(简洁版,中低饱和度)==============
def plot_fuel_share_trend_simple(data, save_path='fuel_share_trend.png'):
"""绘制燃油成本占总成本的比例趋势 - 简洁版,无标题,中低饱和度色调"""
years = data['years']
fuel_cents = data['fuel_cents']
total_cents = data['total_cents']
# 计算燃油占比
fuel_share = (fuel_cents / total_cents) * 100
# 创建图表 - 更小但保持2:1比例
fig, ax1 = plt.subplots(figsize=(10, 5))
# 中低饱和度色调
color1 = '#B87373' # 柔和的红色/玫瑰色
color2 = '#6B8FAF' # 柔和的蓝色
color3 = '#7AAE7A' # 柔和的绿色
# 绘制燃油占比(左轴)
ax1.fill_between(years, 0, fuel_share, alpha=0.25, color=color1)
line1, = ax1.plot(years, fuel_share, 'o-', color=color1, linewidth=2,
markersize=6, label='Fuel Share (%)')
ax1.set_xlabel('Year', fontsize=11)
ax1.set_ylabel('Fuel as % of Total Operating Cost', fontsize=11, color=color1)
ax1.tick_params(axis='y', labelcolor=color1)
ax1.set_ylim(0, 45)
# 添加平均线
avg_share = np.mean(fuel_share)
ax1.axhline(y=avg_share, color=color1, linestyle='--', linewidth=1.2, alpha=0.6)
ax1.text(years[-1]+0.5, avg_share+1, f'Avg: {avg_share:.1f}%',
fontsize=10, color=color1, fontweight='bold')
# 右轴:绝对成本
ax2 = ax1.twinx()
line2, = ax2.plot(years, total_cents, 's--', color=color2, linewidth=1.8,
markersize=5, alpha=0.75, label='Total CASM (cents)')
line3, = ax2.plot(years, fuel_cents, '^--', color=color3, linewidth=1.8,
markersize=5, alpha=0.75, label='Fuel CASM (cents)')
ax2.set_ylabel('Cost per ASM (cents)', fontsize=11, color=color2)
ax2.tick_params(axis='y', labelcolor=color2)
# 标注关键年份
# 2008年油价高峰
idx_2008 = np.where(years == 2008)[0][0]
ax1.annotate(f'2008 Oil Crisis\n{fuel_share[idx_2008]:.1f}%',
xy=(2008, fuel_share[idx_2008]),
xytext=(2005, fuel_share[idx_2008]+8),
fontsize=9, ha='center',
arrowprops=dict(arrowstyle='->', color='#888888'),
bbox=dict(boxstyle='round,pad=0.3', facecolor='#FFF5E6', alpha=0.8))
# 2015年油价低谷
idx_2015 = np.where(years == 2015)[0][0]
ax1.annotate(f'2015 Oil Crash\n{fuel_share[idx_2015]:.1f}%',
xy=(2015, fuel_share[idx_2015]),
xytext=(2017, fuel_share[idx_2015]-8),
fontsize=9, ha='center',
arrowprops=dict(arrowstyle='->', color='#888888'),
bbox=dict(boxstyle='round,pad=0.3', facecolor='#E6F3FA', alpha=0.8))
# 图例
lines = [line1, line2, line3]
labels = [l.get_label() for l in lines]
ax1.legend(lines, labels, loc='upper left', fontsize=10)
# 添加数据来源
fig.text(0.99, 0.01, 'Data Source: MIT Airline Data Project / US DOT Form 41',
fontsize=8, ha='right', style='italic', alpha=0.6)
plt.tight_layout()
plt.savefig(save_path, dpi=150, bbox_inches='tight')
print(f"图表已保存: {save_path}")
return fig
# ============== 图表7: 燃油-总成本相关性散点图(单独版)==============
def plot_fuel_total_correlation_scatter(data, save_path='fuel_total_correlation.png'):
"""绘制燃油成本与总成本的相关性散点图 - 单独版,无标题,中低饱和度色调"""
years = data['years']
fuel = data['fuel_cents']
total = data['total_cents']
# 计算相关系数
correlation = np.corrcoef(fuel, total)[0, 1]
# 线性回归
coeffs = np.polyfit(fuel, total, 1)
poly = np.poly1d(coeffs)
fuel_range = np.linspace(fuel.min(), fuel.max(), 100)
# 创建图表 - 与fuel_share_trend类似的尺寸比例
fig, ax = plt.subplots(figsize=(10, 5))
# 中低饱和度色调 - 与fuel_share_trend类似但不完全相同
scatter_cmap = 'YlGnBu' # 柔和的黄-绿-蓝渐变色
line_color = '#9B7B6B' # 柔和的棕红色
text_bg_color = '#D4E8D4' # 柔和的淡绿色
# 散点图
scatter = ax.scatter(fuel, total, c=years, cmap=scatter_cmap, s=90, alpha=0.85,
edgecolors='white', linewidth=1.2)
# 回归线
ax.plot(fuel_range, poly(fuel_range), '--', color=line_color, linewidth=2,
label=f'Linear Fit (R²={correlation**2:.3f})')
# 颜色条
cbar = plt.colorbar(scatter, ax=ax)
cbar.set_label('Year', fontsize=10)
ax.set_xlabel('Fuel Cost per ASM (cents)', fontsize=11)
ax.set_ylabel('Total Cost per ASM (cents)', fontsize=11)
ax.legend(fontsize=10, loc='lower right')
ax.grid(True, alpha=0.3)
# 添加相关性解释
ax.text(0.05, 0.95, f'Pearson r = {correlation:.3f}\nEnergy drives ~{correlation**2*100:.0f}% of cost variance',
transform=ax.transAxes, fontsize=10, verticalalignment='top',
bbox=dict(boxstyle='round', facecolor=text_bg_color, alpha=0.8))
# 添加数据来源
fig.text(0.99, 0.01, 'Data Source: MIT Airline Data Project / US DOT Form 41',
fontsize=8, ha='right', style='italic', alpha=0.6)
plt.tight_layout()
plt.savefig(save_path, dpi=150, bbox_inches='tight')
print(f"图表已保存: {save_path}")
return fig
# ============== 主程序 ==============
if __name__ == "__main__":

Binary file not shown.

Before

Width:  |  Height:  |  Size: 196 KiB

After

Width:  |  Height:  |  Size: 138 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 91 KiB

Binary file not shown.