import os import pickle import matplotlib import matplotlib.pyplot as plt import numpy as np import pandas as pd import seaborn as sns matplotlib.rc('text', usetex=True) pd.options.display.notebook_repr_html = False def plot_optimization_result(datasource, directory): # data source is dataframe sns.set_theme(style='whitegrid') # "white", "dark", "whitegrid", "darkgrid", "ticks" plt.rcParams["figure.figsize"] = (16, 9) fig, axs = plt.subplots(2, 2) plt.subplots_adjust(wspace=0.7, hspace=0.3) plt.autoscale(tight=True) T = np.array([i for i in range(24)]) # 绘制步长成本 in ax[0] axs[0, 0].cla() axs[0, 0].set_ylabel('Costs') axs[0, 0].set_xlabel('Time(h)') axs[0, 0].bar(T, datasource['step_cost']) # axs[0,0].set_xticks([i for i in range(24)],[i for i in range(1,25)]) # 绘制soc和价格 in ax[1] axs[0, 1].cla() # 设置第一个 y 轴 axs[0, 1].set_ylabel('Price') axs[0, 1].set_xlabel('Time(h)') line1, = axs[0, 1].plot(T, datasource['price'], drawstyle='steps-mid', label='Price', color='pink') # 创建第二个 y 轴 ax2 = axs[0, 1].twinx() ax2.set_ylabel('SOC') line2, = ax2.plot(T, datasource['soc'], drawstyle='steps-mid', label='SOC', color='grey') # 为每个轴分别创建图例 lines = [line1, line2] labels = [line.get_label() for line in lines] axs[0, 1].legend(lines, labels, loc='upper right', bbox_to_anchor=(1.4, 1), fontsize=12, frameon=False, labelspacing=0.3) # 绘制累计发电量和消耗量 in ax[2] axs[1, 0].cla() axs[1, 0].set_ylabel('Outputs of DGs and Battery') axs[1, 0].set_xlabel('Time(h)') # 处理电池充放电数据 battery_positive = np.array(datasource['battery_energy_change']) battery_negative = np.array(datasource['battery_energy_change']) battery_positive = np.maximum(battery_positive, 0) # charge battery_negative = np.minimum(battery_negative, 0) # discharge # 处理电网进出口数据 imported_from_grid = np.array(datasource['grid_import']) exported_2_grid = np.array(datasource['grid_export']) axs[1, 0].bar(T, datasource['gen1'], label='Gen1') axs[1, 0].bar(T, datasource['gen2'], label='Gen2', bottom=datasource['gen1']) axs[1, 0].bar(T, datasource['gen3'], label='Gen3', bottom=datasource['gen2'] + datasource['gen1']) axs[1, 0].bar(T, -battery_positive, color='blue', hatch='/', label='ESS charge') axs[1, 0].bar(T, -battery_negative, hatch='/', label='ESS discharge', bottom=datasource['gen3'] + datasource['gen2'] + datasource['gen1']) # 生成即进口 axs[1, 0].bar(T, imported_from_grid, label='Grid import', bottom=-battery_negative + datasource['gen3'] + datasource['gen2'] + datasource['gen1']) # 负载即出口 axs[1, 0].bar(T, -exported_2_grid, label='Grid export', bottom=-battery_positive) # 绘制净负载曲线 axs[1, 0].plot(T, datasource['netload'], label='Netload', drawstyle='steps-mid', alpha=0.7) axs[1, 0].legend(loc='upper right', bbox_to_anchor=(1.4, 1), fontsize=12, frameon=False, labelspacing=0.3) # axs[1,0].set_xticks([i for i in range(24)],[i for i in range(1,25)]) fig.savefig(f"{directory}/optimization_information.svg", format='svg', dpi=600, bbox_inches='tight') print('optimization results have been ploted and saved') def plot_evaluation_information(datasource, directory): sns.set_theme(style='whitegrid') with open(datasource, 'rb') as tf: test_data = pickle.load(tf) # 用条形图表示每一步的不平衡和奖励 plt.rcParams["figure.figsize"] = (16, 9) fig, axs = plt.subplots(2, 2) plt.subplots_adjust(wspace=0.7, hspace=0.3) plt.autoscale(tight=True) # 为评估环境准备数据 eval_data = pd.DataFrame(test_data['system_info']) eval_data.columns = ['time_step', 'price', 'netload', 'action', 'real_action', 'soc', 'battery', 'gen1', 'gen2', 'gen3', 'temperature', 'irradiance', 'unbalance', 'operation_cost'] # 绘制不平衡度 in axs[0] axs[0, 0].cla() axs[0, 0].set_ylabel('Unbalance of Generation and Load') axs[0, 0].bar(eval_data['time_step'], eval_data['unbalance'], label='Exchange with Grid', width=0.4) axs[0, 0].bar(eval_data['time_step'] + 0.4, eval_data['netload'], label='Netload', width=0.4) axs[0, 0].legend(loc='upper right', bbox_to_anchor=(1.4, 1), fontsize=12, frameon=False, labelspacing=0.5) # axs[0,0].set_xticks([i for i in range(24)],[i for i in range(1,25)]) # 绘制能源充/放电与价格关系图 in ax[1] axs[0, 1].cla() axs[0, 1].set_ylabel('Price') axs[0, 1].set_xlabel('Time Steps') line1, = axs[0, 1].plot(eval_data['time_step'], eval_data['price'], drawstyle='steps-mid', label='Price', color='pink') ax2 = axs[0, 1].twinx() ax2.set_ylabel('SOC') line2, = ax2.plot(eval_data['time_step'], eval_data['soc'], drawstyle='steps-mid', label='SOC', color='grey') lines = [line1, line2] labels = [line.get_label() for line in lines] axs[0, 1].legend(lines, labels, loc='upper right', bbox_to_anchor=(1.4, 1), fontsize=12, frameon=False, labelspacing=0.3) # 绘制发电量和负载量 in ax[2] axs[1, 0].cla() axs[1, 0].set_ylabel('Outputs of Units and Netload (kWh)') # axs[1,0].set_xticks([i for i in range(24)], [i for i in range(1, 25)]) battery_positive = np.array(eval_data['battery']) battery_negative = np.array(eval_data['battery']) battery_positive = np.maximum(battery_positive, 0) # charge battery_negative = np.minimum(battery_negative, 0) # discharge imported_from_grid = np.minimum(np.array(eval_data['unbalance']), 0) exported_2_grid = np.maximum(np.array(eval_data['unbalance']), 0) x = eval_data['time_step'] axs[1, 0].bar(x, eval_data['gen1'], label='Gen1') axs[1, 0].bar(x, eval_data['gen2'], label='Gen2', bottom=eval_data['gen1']) axs[1, 0].bar(x, eval_data['gen3'], label='Gen3', bottom=eval_data['gen1'] + eval_data['gen2']) axs[1, 0].bar(x, -battery_positive, color='blue', hatch='/', label='ESS charge') axs[1, 0].bar(x, -battery_negative, label='ESS discharge', hatch='/', bottom=eval_data['gen1'] + eval_data['gen2'] + eval_data['gen3']) axs[1, 0].bar(x, -imported_from_grid, label='Grid import', bottom=eval_data['gen1'] + eval_data['gen2'] + eval_data['gen3'] - battery_negative) axs[1, 0].bar(x, -exported_2_grid, label='Grid export', bottom=-battery_positive) axs[1, 0].plot(x, eval_data['netload'], drawstyle='steps-mid', label='Netload') axs[1, 0].legend(loc='upper right', bbox_to_anchor=(1.4, 1), fontsize=12, frameon=False, labelspacing=0.3) # 绘制奖励 in axs[3] axs[1, 1].cla() axs[1, 1].set_ylabel('Costs') axs[1, 1].bar(eval_data['time_step'], eval_data['operation_cost']) fig.savefig(f"{directory}/evaluation_information.svg", format='svg', dpi=600, bbox_inches='tight') print('evaluation figure have been ploted and saved') def make_dir(directory, feature_change): cwd = f'{directory}/DRL_{feature_change}_plots' os.makedirs(cwd, exist_ok=True) return cwd class PlotArgs: def __init__(self) -> None: self.cwd = None self.feature_change = None self.plot_on = None