Skip to content

Commit 80ee01e

Browse files
committed
Shed Load included in dispatch plots (hatched)
1 parent d65a1d8 commit 80ee01e

File tree

1 file changed

+36
-7
lines changed

1 file changed

+36
-7
lines changed

dispaset/postprocessing/plot.py

Lines changed: 36 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
from .postprocessing import get_imports, get_plot_data, filter_by_zone
1212

1313

14-
def plot_dispatch(demand, plotdata, level=None, curtailment=None, rng=None,
14+
def plot_dispatch(demand, plotdata, level=None, curtailment=None, shedload=None, rng=None,
1515
alpha=None, figsize=(13, 6)):
1616
"""
1717
Function that plots the dispatch data and the reservoir level as a cumulative sum
@@ -20,6 +20,7 @@ def plot_dispatch(demand, plotdata, level=None, curtailment=None, rng=None,
2020
:param plotdata: Pandas Dataframe with the data to be plotted. Negative columns should be at the beginning. Output of the function GetPlotData
2121
:param level: Optional pandas series with an aggregated reservoir level for the considered zone.
2222
:param curtailment: Optional pandas series with the value of the curtailment
23+
:param shedload: Optional pandas series with the value of the shed load
2324
:param rng: Indexes of the values to be plotted. If undefined, the first week is plotted
2425
"""
2526
import matplotlib.patches as mpatches
@@ -34,7 +35,7 @@ def plot_dispatch(demand, plotdata, level=None, curtailment=None, rng=None,
3435
raise ValueError()
3536
elif rng[0] < plotdata.index[0] or rng[0] > plotdata.index[-1] or rng[-1] < plotdata.index[0] or rng[-1] > \
3637
plotdata.index[-1]:
37-
logging.warn('Plotting range is not properly defined, considering the first simulated week')
38+
logging.warning('Plotting range is not properly defined, considering the first simulated week')
3839
pdrng = plotdata.index[:min(len(plotdata) - 1, 7 * 24)]
3940
else:
4041
pdrng = rng
@@ -127,12 +128,32 @@ def plot_dispatch(demand, plotdata, level=None, curtailment=None, rng=None,
127128
axes[1].yaxis.label.set_fontsize(12)
128129
line_SOC = mlines.Line2D([], [], color='black', alpha=alpha, label='Reservoir', linestyle=':')
129130

131+
if isinstance(shedload, pd.Series):
132+
if not shedload.index.equals(demand.index):
133+
logging.error('The shedload time series must have the same index as the demand')
134+
sys.exit(1)
135+
reduced_demand = demand - shedload
136+
axes[0].plot(pdrng, reduced_demand[pdrng], color='k', alpha=alpha, linestyle='dashed')
137+
line_shedload = mlines.Line2D([], [], color='black', alpha=alpha, label='Shed Load', linestyle='dashed')
138+
130139
line_demand = mlines.Line2D([], [], color='black', label='Load')
131-
plt.legend(handles=[line_demand] + patches[::-1], loc=4)
132-
if level is None:
133-
plt.legend(handles=[line_demand] + patches[::-1], loc=4)
140+
# plt.legend(handles=[line_demand] + patches[::-1], loc=4)
141+
142+
if shedload is None and level is None:
143+
plt.legend(handles=[line_demand] + patches[::-1], loc=4, bbox_to_anchor=(1.2, 1.3))
144+
if shedload is None:
145+
plt.legend(handles=[line_demand] + [line_SOC] + patches[::-1], loc=4, bbox_to_anchor=(1.2, 1.3))
146+
elif level is None:
147+
plt.legend(handles=[line_demand] + [line_shedload] + patches[::-1], loc=4, bbox_to_anchor=(1.2, 1.3))
148+
axes[0].fill_between(demand.index, demand, reduced_demand, facecolor="none", hatch="X", edgecolor="k",
149+
linestyle='dashed')
134150
else:
135-
plt.legend(title='Dispatch for ' + demand.name[1], handles=[line_demand] + [line_SOC] + patches[::-1], loc=4)
151+
plt.legend(title='Dispatch for ' + demand.name[1], handles=[line_demand] + [line_shedload] + [line_SOC] +
152+
patches[::-1], loc=4, bbox_to_anchor=(1.2, 1.3))
153+
axes[0].fill_between(demand.index, demand, reduced_demand, facecolor="none", hatch="X", edgecolor="k",
154+
linestyle='dashed')
155+
156+
plt.subplots_adjust(right=0.8)
136157
plt.show()
137158

138159

@@ -249,6 +270,7 @@ def plot_energy_zone_fuel(inputs, results, PPindicators):
249270
demand = inputs['param_df']['Demand']['DA'].sum() / 1E6
250271
ax.barh(demand, left=ax.get_xticks() - 0.4, width=[0.8] * len(demand), height=ax.get_ylim()[1] * 0.005, linewidth=2,
251272
color='k')
273+
plt.show()
252274
return ax
253275

254276

@@ -324,16 +346,23 @@ def plot_zone(inputs, results, z='', rng=None, rug_plot=True):
324346
# if 'OutputShedLoad' in results:
325347
if 'OutputShedLoad' in results and z in results['OutputShedLoad']:
326348
shed_load = results['OutputShedLoad'][z] / 1000 # GW
349+
shed_load = pd.Series(shed_load, index=demand.index).fillna(0)
327350
else:
328351
shed_load = pd.Series(0, index=demand.index) / 1000 # GW
329352
diff = (sum_generation - demand + shed_load).abs()
330353
if diff.max() > 0.01 * demand.max():
331354
logging.critical('There is up to ' + str(
332355
diff.max() / demand.max() * 100) + '% difference in the instantaneous energy balance of zone ' + z)
333356

334-
if 'OutputCurtailedPower' in results and z in results['OutputCurtailedPower']:
357+
if 'OutputCurtailedPower' in results and z in results['OutputCurtailedPower'] \
358+
and 'OutputShedLoad' in results and z in results['OutputShedLoad']:
359+
curtailment = results['OutputCurtailedPower'][z] / 1000 # GW
360+
plot_dispatch(demand, plotdata, level, curtailment=curtailment, shedload = shed_load, rng=rng)
361+
elif 'OutputCurtailedPower' in results and z in results['OutputCurtailedPower']:
335362
curtailment = results['OutputCurtailedPower'][z] / 1000 # GW
336363
plot_dispatch(demand, plotdata, level, curtailment=curtailment, rng=rng)
364+
elif 'OutputShedLoad' in results and z in results['OutputShedLoad']:
365+
plot_dispatch(demand, plotdata, level, shedload = shed_load, rng=rng)
337366
else:
338367
plot_dispatch(demand, plotdata, level, rng=rng)
339368

0 commit comments

Comments
 (0)