增加正负显示购电量。
This commit is contained in:
206
main.py
206
main.py
@@ -11,6 +11,8 @@ import matplotlib
|
|||||||
matplotlib.use('TkAgg') # 设置为TkAgg后端以支持图形窗口显示
|
matplotlib.use('TkAgg') # 设置为TkAgg后端以支持图形窗口显示
|
||||||
import matplotlib.pyplot as plt
|
import matplotlib.pyplot as plt
|
||||||
import numpy as np
|
import numpy as np
|
||||||
|
import pandas as pd
|
||||||
|
from datetime import datetime
|
||||||
from storage_optimization import optimize_storage_capacity, SystemParameters
|
from storage_optimization import optimize_storage_capacity, SystemParameters
|
||||||
from excel_reader import read_excel_data, create_excel_template, analyze_excel_data
|
from excel_reader import read_excel_data, create_excel_template, analyze_excel_data
|
||||||
|
|
||||||
@@ -54,6 +56,7 @@ def plot_system_curves(solar_output, wind_output, thermal_output, load_demand, r
|
|||||||
sampled_storage = result['storage_profile'][::sample_rate]
|
sampled_storage = result['storage_profile'][::sample_rate]
|
||||||
sampled_charge = result['charge_profile'][::sample_rate]
|
sampled_charge = result['charge_profile'][::sample_rate]
|
||||||
sampled_discharge = result['discharge_profile'][::sample_rate]
|
sampled_discharge = result['discharge_profile'][::sample_rate]
|
||||||
|
sampled_grid_feed_in = result['grid_feed_in'][::sample_rate]
|
||||||
else:
|
else:
|
||||||
title_suffix = " (24小时)"
|
title_suffix = " (24小时)"
|
||||||
sampled_hours = hours
|
sampled_hours = hours
|
||||||
@@ -64,9 +67,10 @@ def plot_system_curves(solar_output, wind_output, thermal_output, load_demand, r
|
|||||||
sampled_storage = result['storage_profile']
|
sampled_storage = result['storage_profile']
|
||||||
sampled_charge = result['charge_profile']
|
sampled_charge = result['charge_profile']
|
||||||
sampled_discharge = result['discharge_profile']
|
sampled_discharge = result['discharge_profile']
|
||||||
|
sampled_grid_feed_in = result['grid_feed_in']
|
||||||
|
|
||||||
# 创建图形
|
# 创建图形(4个子图)
|
||||||
fig, (ax1, ax2, ax3) = plt.subplots(3, 1, figsize=(14, 12))
|
fig, (ax1, ax2, ax3, ax4) = plt.subplots(4, 1, figsize=(14, 16))
|
||||||
fig.suptitle('多能互补系统24小时运行曲线', fontsize=16, fontweight='bold')
|
fig.suptitle('多能互补系统24小时运行曲线', fontsize=16, fontweight='bold')
|
||||||
|
|
||||||
# === 第一个子图:发电和负荷曲线 ===
|
# === 第一个子图:发电和负荷曲线 ===
|
||||||
@@ -111,6 +115,31 @@ def plot_system_curves(solar_output, wind_output, thermal_output, load_demand, r
|
|||||||
ax3.set_xlim(0, max(sampled_hours))
|
ax3.set_xlim(0, max(sampled_hours))
|
||||||
ax3.set_ylim(bottom=0)
|
ax3.set_ylim(bottom=0)
|
||||||
|
|
||||||
|
# === 第四个子图:购电量和上网电量曲线 ===
|
||||||
|
# 直接使用原始数据:正值表示上网电量,负值表示购电量
|
||||||
|
grid_power = sampled_grid_feed_in
|
||||||
|
|
||||||
|
# 绘制电网交互电量(正值上网,负值购电)
|
||||||
|
colors = ['brown' if x >= 0 else 'purple' for x in grid_power]
|
||||||
|
ax4.bar(sampled_hours, grid_power, color=colors, alpha=0.7, label='电网交互电量')
|
||||||
|
|
||||||
|
# 添加零线
|
||||||
|
ax4.axhline(y=0, color='black', linestyle='-', linewidth=0.5)
|
||||||
|
|
||||||
|
# 添加图例说明
|
||||||
|
from matplotlib.patches import Patch
|
||||||
|
legend_elements = [
|
||||||
|
Patch(facecolor='brown', alpha=0.7, label='上网电量 (+)'),
|
||||||
|
Patch(facecolor='purple', alpha=0.7, label='购电量 (-)')
|
||||||
|
]
|
||||||
|
ax4.legend(handles=legend_elements, loc='upper right')
|
||||||
|
|
||||||
|
ax4.set_xlabel('时间 (小时)')
|
||||||
|
ax4.set_ylabel('功率 (MW)')
|
||||||
|
ax4.set_title(f'电网交互电量{title_suffix} (正值:上网, 负值:购电)')
|
||||||
|
ax4.grid(True, alpha=0.3)
|
||||||
|
ax4.set_xlim(0, max(sampled_hours))
|
||||||
|
|
||||||
# 调整布局
|
# 调整布局
|
||||||
plt.tight_layout()
|
plt.tight_layout()
|
||||||
|
|
||||||
@@ -146,6 +175,173 @@ def plot_system_curves(solar_output, wind_output, thermal_output, load_demand, r
|
|||||||
print(f"弃光率: {result['total_curtailment_solar_ratio']:.3f}")
|
print(f"弃光率: {result['total_curtailment_solar_ratio']:.3f}")
|
||||||
print(f"上网电量比例: {result['total_grid_feed_in_ratio']:.3f}")
|
print(f"上网电量比例: {result['total_grid_feed_in_ratio']:.3f}")
|
||||||
|
|
||||||
|
# 计算购电和上网电量统计
|
||||||
|
total_grid_feed_in = sum(result['grid_feed_in'])
|
||||||
|
total_grid_purchase = sum(-x for x in result['grid_feed_in'] if x < 0) # 购电量
|
||||||
|
total_grid_feed_out = sum(x for x in result['grid_feed_in'] if x > 0) # 上网电量
|
||||||
|
|
||||||
|
print(f"\n=== 电网交互统计 ===")
|
||||||
|
if total_grid_feed_in >= 0:
|
||||||
|
print(f"净上网电量: {total_grid_feed_in:.2f} MWh")
|
||||||
|
else:
|
||||||
|
print(f"净购电量: {-total_grid_feed_in:.2f} MWh")
|
||||||
|
print(f"总购电量: {total_grid_purchase:.2f} MWh")
|
||||||
|
print(f"总上网电量: {total_grid_feed_out:.2f} MWh")
|
||||||
|
|
||||||
|
|
||||||
|
def export_results_to_excel(solar_output, wind_output, thermal_output, load_demand, result, params, filename=None):
|
||||||
|
"""
|
||||||
|
将优化结果导出到Excel文件
|
||||||
|
|
||||||
|
Args:
|
||||||
|
solar_output: 光伏出力曲线 (MW)
|
||||||
|
wind_output: 风电出力曲线 (MW)
|
||||||
|
thermal_output: 火电出力曲线 (MW)
|
||||||
|
load_demand: 负荷曲线 (MW)
|
||||||
|
result: 优化结果字典
|
||||||
|
params: 系统参数
|
||||||
|
filename: 输出文件名,如果为None则自动生成
|
||||||
|
"""
|
||||||
|
if filename is None:
|
||||||
|
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
|
||||||
|
filename = f"storage_optimization_results_{timestamp}.xlsx"
|
||||||
|
|
||||||
|
print(f"\n正在导出结果到Excel文件: {filename}")
|
||||||
|
|
||||||
|
# 准备数据
|
||||||
|
hours = list(range(1, len(solar_output) + 1))
|
||||||
|
|
||||||
|
# 分离购电和上网电量
|
||||||
|
grid_purchase = []
|
||||||
|
grid_feed_out = []
|
||||||
|
|
||||||
|
for power in result['grid_feed_in']:
|
||||||
|
if power < 0:
|
||||||
|
grid_purchase.append(-power) # 购电,转换为正值
|
||||||
|
grid_feed_out.append(0)
|
||||||
|
else:
|
||||||
|
grid_purchase.append(0)
|
||||||
|
grid_feed_out.append(power) # 上网电量
|
||||||
|
|
||||||
|
# 创建主要数据DataFrame
|
||||||
|
data_df = pd.DataFrame({
|
||||||
|
'小时': hours,
|
||||||
|
'光伏出力(MW)': solar_output,
|
||||||
|
'风电出力(MW)': wind_output,
|
||||||
|
'火电出力(MW)': thermal_output,
|
||||||
|
'总发电量(MW)': [solar_output[i] + wind_output[i] + thermal_output[i] for i in range(len(solar_output))],
|
||||||
|
'负荷需求(MW)': load_demand,
|
||||||
|
'储能充电(MW)': result['charge_profile'],
|
||||||
|
'储能放电(MW)': result['discharge_profile'],
|
||||||
|
'储能状态(MWh)': result['storage_profile'],
|
||||||
|
'弃风量(MW)': result['curtailed_wind'],
|
||||||
|
'弃光量(MW)': result['curtailed_solar'],
|
||||||
|
'购电量(MW)': grid_purchase,
|
||||||
|
'上网电量(MW)': grid_feed_out
|
||||||
|
})
|
||||||
|
|
||||||
|
# 创建统计信息DataFrame
|
||||||
|
total_grid_feed_in = sum(result['grid_feed_in'])
|
||||||
|
total_grid_purchase = sum(-x for x in result['grid_feed_in'] if x < 0) # 购电量
|
||||||
|
total_grid_feed_out = sum(x for x in result['grid_feed_in'] if x > 0) # 上网电量
|
||||||
|
|
||||||
|
stats_df = pd.DataFrame({
|
||||||
|
'指标': [
|
||||||
|
'所需储能总容量',
|
||||||
|
'最大储能状态',
|
||||||
|
'最小储能状态',
|
||||||
|
'总充电量',
|
||||||
|
'总放电量',
|
||||||
|
'弃风率',
|
||||||
|
'弃光率',
|
||||||
|
'上网电量比例',
|
||||||
|
'能量平衡校验',
|
||||||
|
'净购电量/净上网电量',
|
||||||
|
'总购电量',
|
||||||
|
'总上网电量',
|
||||||
|
'容量限制是否达到'
|
||||||
|
],
|
||||||
|
'数值': [
|
||||||
|
f"{result['required_storage_capacity']:.2f} MWh",
|
||||||
|
f"{max(result['storage_profile']):.2f} MWh",
|
||||||
|
f"{min(result['storage_profile']):.2f} MWh",
|
||||||
|
f"{sum(result['charge_profile']):.2f} MWh",
|
||||||
|
f"{sum(result['discharge_profile']):.2f} MWh",
|
||||||
|
f"{result['total_curtailment_wind_ratio']:.3f}",
|
||||||
|
f"{result['total_curtailment_solar_ratio']:.3f}",
|
||||||
|
f"{result['total_grid_feed_in_ratio']:.3f}",
|
||||||
|
"通过" if result['energy_balance_check'] else "未通过",
|
||||||
|
f"{-total_grid_feed_in:.2f} MWh" if total_grid_feed_in < 0 else f"{total_grid_feed_in:.2f} MWh",
|
||||||
|
f"{total_grid_purchase:.2f} MWh",
|
||||||
|
f"{total_grid_feed_out:.2f} MWh",
|
||||||
|
"是" if result['capacity_limit_reached'] else "否"
|
||||||
|
]
|
||||||
|
})
|
||||||
|
|
||||||
|
# 创建系统参数DataFrame
|
||||||
|
params_df = pd.DataFrame({
|
||||||
|
'参数名称': [
|
||||||
|
'最大弃风率',
|
||||||
|
'最大弃光率',
|
||||||
|
'最大上网电量比例',
|
||||||
|
'储能效率',
|
||||||
|
'放电倍率',
|
||||||
|
'充电倍率',
|
||||||
|
'最大储能容量'
|
||||||
|
],
|
||||||
|
'参数值': [
|
||||||
|
params.max_curtailment_wind,
|
||||||
|
params.max_curtailment_solar,
|
||||||
|
params.max_grid_ratio,
|
||||||
|
params.storage_efficiency,
|
||||||
|
params.discharge_rate,
|
||||||
|
params.charge_rate,
|
||||||
|
params.max_storage_capacity if params.max_storage_capacity is not None else "无限制"
|
||||||
|
],
|
||||||
|
'单位': [
|
||||||
|
"比例",
|
||||||
|
"比例",
|
||||||
|
"比例",
|
||||||
|
"效率",
|
||||||
|
"C-rate",
|
||||||
|
"C-rate",
|
||||||
|
"MWh"
|
||||||
|
]
|
||||||
|
})
|
||||||
|
|
||||||
|
# 写入Excel文件
|
||||||
|
with pd.ExcelWriter(filename, engine='openpyxl') as writer:
|
||||||
|
# 写入主要数据
|
||||||
|
data_df.to_excel(writer, sheet_name='运行数据', index=False)
|
||||||
|
|
||||||
|
# 写入统计信息
|
||||||
|
stats_df.to_excel(writer, sheet_name='统计结果', index=False)
|
||||||
|
|
||||||
|
# 写入系统参数
|
||||||
|
params_df.to_excel(writer, sheet_name='系统参数', index=False)
|
||||||
|
|
||||||
|
# 创建说明工作表
|
||||||
|
description_df = pd.DataFrame({
|
||||||
|
'项目': [
|
||||||
|
'文件说明',
|
||||||
|
'生成时间',
|
||||||
|
'数据长度',
|
||||||
|
'数据内容',
|
||||||
|
'注意事项'
|
||||||
|
],
|
||||||
|
'内容': [
|
||||||
|
'多能互补系统储能容量优化结果',
|
||||||
|
datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
|
||||||
|
f"{len(solar_output)} 小时",
|
||||||
|
'包含发电、负荷、储能、弃风弃光、购电上网等完整数据',
|
||||||
|
'负值表示购电,正值表示上网电量'
|
||||||
|
]
|
||||||
|
})
|
||||||
|
description_df.to_excel(writer, sheet_name='说明', index=False)
|
||||||
|
|
||||||
|
print(f"结果已成功导出到: {filename}")
|
||||||
|
return filename
|
||||||
|
|
||||||
|
|
||||||
def generate_yearly_data():
|
def generate_yearly_data():
|
||||||
"""生成8760小时的示例数据"""
|
"""生成8760小时的示例数据"""
|
||||||
@@ -313,6 +509,12 @@ def main():
|
|||||||
print("正在绘制系统运行曲线...")
|
print("正在绘制系统运行曲线...")
|
||||||
plot_system_curves(solar_output, wind_output, thermal_output, load_demand, result, show_window, display_only)
|
plot_system_curves(solar_output, wind_output, thermal_output, load_demand, result, show_window, display_only)
|
||||||
|
|
||||||
|
# 导出结果到Excel
|
||||||
|
try:
|
||||||
|
export_results_to_excel(solar_output, wind_output, thermal_output, load_demand, result, params)
|
||||||
|
except Exception as e:
|
||||||
|
print(f"导出Excel文件失败:{str(e)}")
|
||||||
|
|
||||||
if display_only:
|
if display_only:
|
||||||
print("\n正在显示图形窗口...")
|
print("\n正在显示图形窗口...")
|
||||||
elif show_window:
|
elif show_window:
|
||||||
|
|||||||
Reference in New Issue
Block a user