修复图表乱码。

This commit is contained in:
dmy
2025-12-25 21:05:53 +08:00
parent 02b2fdc309
commit 974ac6d6db

View File

@@ -11,6 +11,10 @@ import numpy as np
import matplotlib.pyplot as plt import matplotlib.pyplot as plt
from storage_optimization import optimize_storage_capacity, SystemParameters from storage_optimization import optimize_storage_capacity, SystemParameters
# 配置matplotlib支持中文显示
plt.rcParams['font.sans-serif'] = ['SimHei', 'Microsoft YaHei', 'DejaVu Sans']
plt.rcParams['axes.unicode_minus'] = False # 解决负号显示问题
def example_1_basic_scenario(): def example_1_basic_scenario():
"""示例1: 基础场景""" """示例1: 基础场景"""
@@ -48,7 +52,13 @@ def example_1_basic_scenario():
print(f"实际上网电量比例: {result['total_grid_feed_in_ratio']:.3f} (约束: {params.max_grid_ratio})") print(f"实际上网电量比例: {result['total_grid_feed_in_ratio']:.3f} (约束: {params.max_grid_ratio})")
print(f"能量平衡校验: {'通过' if result['energy_balance_check'] else '未通过'}") print(f"能量平衡校验: {'通过' if result['energy_balance_check'] else '未通过'}")
return result return {
'result': result,
'solar_output': solar_output,
'wind_output': wind_output,
'thermal_output': thermal_output,
'load_demand': load_demand
}
def example_2_high_renewable_scenario(): def example_2_high_renewable_scenario():
@@ -85,7 +95,13 @@ def example_2_high_renewable_scenario():
print(f"实际上网电量比例: {result['total_grid_feed_in_ratio']:.3f}") print(f"实际上网电量比例: {result['total_grid_feed_in_ratio']:.3f}")
print(f"能量平衡校验: {'通过' if result['energy_balance_check'] else '未通过'}") print(f"能量平衡校验: {'通过' if result['energy_balance_check'] else '未通过'}")
return result return {
'result': result,
'solar_output': solar_output,
'wind_output': wind_output,
'thermal_output': thermal_output,
'load_demand': load_demand
}
def example_3_winter_scenario(): def example_3_winter_scenario():
@@ -122,48 +138,94 @@ def example_3_winter_scenario():
print(f"实际上网电量比例: {result['total_grid_feed_in_ratio']:.3f}") print(f"实际上网电量比例: {result['total_grid_feed_in_ratio']:.3f}")
print(f"能量平衡校验: {'通过' if result['energy_balance_check'] else '未通过'}") print(f"能量平衡校验: {'通过' if result['energy_balance_check'] else '未通过'}")
return result return {
'result': result,
'solar_output': solar_output,
'wind_output': wind_output,
'thermal_output': thermal_output,
'load_demand': load_demand
}
def plot_results(result, title): def plot_results(result, title, solar_output, wind_output, thermal_output, load_demand):
"""绘制结果图表""" """绘制结果图表"""
hours = list(range(24)) hours = list(range(24))
fig, ((ax1, ax2), (ax3, ax4)) = plt.subplots(2, 2, figsize=(15, 10)) fig, ((ax1, ax2), (ax3, ax4), (ax5, ax6)) = plt.subplots(3, 2, figsize=(16, 12))
fig.suptitle(title, fontsize=16) fig.suptitle(title, fontsize=16)
# 储能状态 # 发电与负荷对比
ax1.plot(hours, result['storage_profile'], 'b-', linewidth=2) ax1.plot(hours, load_demand, 'r-', linewidth=2, label='负荷需求')
ax1.set_title('储能状态 (MWh)') ax1.plot(hours, thermal_output, 'b-', linewidth=2, label='火电出力')
ax1.plot(hours, wind_output, 'g-', linewidth=2, label='风电出力')
ax1.plot(hours, solar_output, 'orange', linewidth=2, label='光伏出力')
# 计算总发电量
total_generation = [thermal_output[i] + wind_output[i] + solar_output[i] for i in range(24)]
ax1.plot(hours, total_generation, 'k--', linewidth=1.5, alpha=0.7, label='总发电量')
ax1.set_title('发电与负荷曲线')
ax1.set_xlabel('时间 (小时)') ax1.set_xlabel('时间 (小时)')
ax1.set_ylabel('储能容量 (MWh)') ax1.set_ylabel('功率 (MW)')
ax1.legend()
ax1.grid(True) ax1.grid(True)
# 充放电功率 # 储能状态
ax2.plot(hours, result['charge_profile'], 'g-', label='充电', linewidth=2) ax2.plot(hours, result['storage_profile'], 'b-', linewidth=2)
ax2.plot(hours, [-p for p in result['discharge_profile']], 'r-', label='放电', linewidth=2) ax2.set_title('储能状态 (MWh)')
ax2.set_title('储能充放电功率 (MW)')
ax2.set_xlabel('时间 (小时)') ax2.set_xlabel('时间 (小时)')
ax2.set_ylabel('功率 (MW)') ax2.set_ylabel('储能容量 (MWh)')
ax2.legend()
ax2.grid(True) ax2.grid(True)
# 弃风弃光 # 充放电功率
ax3.plot(hours, result['curtailed_wind'], 'c-', label='弃风', linewidth=2) ax3.plot(hours, result['charge_profile'], 'g-', label='充电', linewidth=2)
ax3.plot(hours, result['curtailed_solar'], 'm-', label='弃光', linewidth=2) ax3.plot(hours, [-p for p in result['discharge_profile']], 'r-', label='放电', linewidth=2)
ax3.set_title('弃风弃光量 (MW)') ax3.set_title('储能充放电功率 (MW)')
ax3.set_xlabel('时间 (小时)') ax3.set_xlabel('时间 (小时)')
ax3.set_ylabel('功率 (MW)') ax3.set_ylabel('功率 (MW)')
ax3.legend() ax3.legend()
ax3.grid(True) ax3.grid(True)
# 上网电量 # 弃风弃光
ax4.plot(hours, result['grid_feed_in'], 'orange', linewidth=2) ax4.plot(hours, result['curtailed_wind'], 'c-', label='弃风', linewidth=2)
ax4.set_title('上网电量 (MW)') ax4.plot(hours, result['curtailed_solar'], 'm-', label='弃光', linewidth=2)
ax4.set_title('弃风弃光量 (MW)')
ax4.set_xlabel('时间 (小时)') ax4.set_xlabel('时间 (小时)')
ax4.set_ylabel('功率 (MW)') ax4.set_ylabel('功率 (MW)')
ax4.legend()
ax4.grid(True) ax4.grid(True)
# 上网电量
ax5.plot(hours, result['grid_feed_in'], 'orange', linewidth=2)
ax5.set_title('上网电量 (MW)')
ax5.set_xlabel('时间 (小时)')
ax5.set_ylabel('功率 (MW)')
ax5.grid(True)
# 能量平衡分析
total_gen = sum(thermal_output) + sum(wind_output) + sum(solar_output)
total_load = sum(load_demand)
total_curtailed = sum(result['curtailed_wind']) + sum(result['curtailed_solar'])
total_grid = sum(result['grid_feed_in'])
total_charge = sum(result['charge_profile'])
total_discharge = sum(result['discharge_profile'])
# 创建能量平衡柱状图
categories = ['总发电量', '总负荷', '弃风弃光', '上网电量', '储能充电', '储能放电']
values = [total_gen, total_load, total_curtailed, total_grid, total_charge, total_discharge]
colors = ['blue', 'red', 'orange', 'green', 'cyan', 'magenta']
bars = ax6.bar(categories, values, color=colors, alpha=0.7)
ax6.set_title('能量平衡分析')
ax6.set_ylabel('能量 (MWh)')
ax6.grid(True, axis='y', alpha=0.3)
# 在柱状图上添加数值标签
for bar, value in zip(bars, values):
height = bar.get_height()
ax6.text(bar.get_x() + bar.get_width()/2., height,
f'{value:.1f}', ha='center', va='bottom', fontsize=9)
plt.tight_layout() plt.tight_layout()
plt.show() plt.show()
@@ -173,31 +235,31 @@ def compare_scenarios():
print("\n=== 场景比较 ===") print("\n=== 场景比较 ===")
# 运行三个场景 # 运行三个场景
result1 = example_1_basic_scenario() data1 = example_1_basic_scenario()
result2 = example_2_high_renewable_scenario() data2 = example_2_high_renewable_scenario()
result3 = example_3_winter_scenario() data3 = example_3_winter_scenario()
# 比较结果 # 比较结果
scenarios = ['基础场景', '高可再生能源场景', '冬季场景'] scenarios = ['基础场景', '高可再生能源场景', '冬季场景']
storage_capacities = [ storage_capacities = [
result1['required_storage_capacity'], data1['result']['required_storage_capacity'],
result2['required_storage_capacity'], data2['result']['required_storage_capacity'],
result3['required_storage_capacity'] data3['result']['required_storage_capacity']
] ]
curtailment_wind = [ curtailment_wind = [
result1['total_curtailment_wind_ratio'], data1['result']['total_curtailment_wind_ratio'],
result2['total_curtailment_wind_ratio'], data2['result']['total_curtailment_wind_ratio'],
result3['total_curtailment_wind_ratio'] data3['result']['total_curtailment_wind_ratio']
] ]
curtailment_solar = [ curtailment_solar = [
result1['total_curtailment_solar_ratio'], data1['result']['total_curtailment_solar_ratio'],
result2['total_curtailment_solar_ratio'], data2['result']['total_curtailment_solar_ratio'],
result3['total_curtailment_solar_ratio'] data3['result']['total_curtailment_solar_ratio']
] ]
grid_feed_in = [ grid_feed_in = [
result1['total_grid_feed_in_ratio'], data1['result']['total_grid_feed_in_ratio'],
result2['total_grid_feed_in_ratio'], data2['result']['total_grid_feed_in_ratio'],
result3['total_grid_feed_in_ratio'] data3['result']['total_grid_feed_in_ratio']
] ]
print("\n场景比较结果:") print("\n场景比较结果:")
@@ -207,7 +269,7 @@ def compare_scenarios():
print(f"{scenario:<15} {storage_capacities[i]:<12.2f} {curtailment_wind[i]:<8.3f} " print(f"{scenario:<15} {storage_capacities[i]:<12.2f} {curtailment_wind[i]:<8.3f} "
f"{curtailment_solar[i]:<8.3f} {grid_feed_in[i]:<8.3f}") f"{curtailment_solar[i]:<8.3f} {grid_feed_in[i]:<8.3f}")
return result1, result2, result3 return data1, data2, data3
if __name__ == "__main__": if __name__ == "__main__":
@@ -215,13 +277,19 @@ if __name__ == "__main__":
print("=" * 50) print("=" * 50)
# 运行示例 # 运行示例
result1, result2, result3 = compare_scenarios() data1, data2, data3 = compare_scenarios()
# 绘制图表如果matplotlib可用 # 绘制图表如果matplotlib可用
try: try:
plot_results(result1, "基础场景储能运行情况") plot_results(data1['result'], "基础场景储能运行情况",
plot_results(result2, "高可再生能源场景储能运行情况") data1['solar_output'], data1['wind_output'],
plot_results(result3, "冬季场景储能运行情况") data1['thermal_output'], data1['load_demand'])
plot_results(data2['result'], "高可再生能源场景储能运行情况",
data2['solar_output'], data2['wind_output'],
data2['thermal_output'], data2['load_demand'])
plot_results(data3['result'], "冬季场景储能运行情况",
data3['solar_output'], data3['wind_output'],
data3['thermal_output'], data3['load_demand'])
except ImportError: except ImportError:
print("\n注意: matplotlib未安装无法绘制图表") print("\n注意: matplotlib未安装无法绘制图表")
print("要安装matplotlib请运行: pip install matplotlib") print("要安装matplotlib请运行: pip install matplotlib")