Skip to content

Commit 54dcc45

Browse files
committed
Differentiate between different storage levels
1 parent b2687f6 commit 54dcc45

File tree

2 files changed

+77
-39
lines changed

2 files changed

+77
-39
lines changed

dispaset/common.py

+22-14
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,21 @@
2424
commons['MeritOrder'] = ['THMS','BATS','BEVS','HDAM','HPHS','FlowOut','GEO','NUC', 'LIG', 'HRD', 'BIO', 'GAS', 'OIL', 'PEA', 'WST', 'OTH', 'SUN', 'WIN', 'FlowIn', 'WAT']
2525

2626
# Colors associated with each fuel:
27-
commons['colors'] = {'LIG': '#af4b9180', 'PEA': '#af4b9199', 'HRD': '#af4b91b2', 'OIL': '#af4b91ff',
27+
# commons['colors'] = {'LIG': '#af4b9180', 'PEA': '#af4b9199', 'HRD': '#af4b91b2', 'OIL': '#af4b91ff',
28+
# # 'GAS': '#d7642dff',
29+
# # 'NUC': '#466eb4ff',
30+
# # 'SUN': '#e6a532ff',
31+
# # 'WIN': '#41afaaff',
32+
# # 'WAT': '#00a0e1ff',
33+
# # 'BIO': '#7daf4bff', 'GEO': '#7daf4bbf',
34+
# # 'Storage': '#b93c46ff', 'FlowIn': '#b93c46b2', 'FlowOut': '#b93c4666',
35+
# # 'OTH': '#b9c33799', 'WST': '#b9c337ff',
36+
# # 'HDAM': '#00a0e1ff',
37+
# # 'HPHS': '#3090C7ff',
38+
# # 'THMS': '#C04000ff',
39+
# # 'BATS': '#41A317ff',
40+
# # 'BEVS': '#CC80FFff'}
41+
commons['colors'] = {'LIG': '#af4b9180', 'PEA': '#af4b9199', 'HRD': 'darkviolet', 'OIL': 'magenta',
2842
'GAS': '#d7642dff',
2943
'NUC': '#466eb4ff',
3044
'SUN': '#e6a532ff',
@@ -33,23 +47,17 @@
3347
'BIO': '#7daf4bff', 'GEO': '#7daf4bbf',
3448
'Storage': '#b93c46ff', 'FlowIn': '#b93c46b2', 'FlowOut': '#b93c4666',
3549
'OTH': '#b9c33799', 'WST': '#b9c337ff',
36-
'HDAM': '#78C7C7',
37-
'HPHS': '#3090C7ff',
50+
'HDAM': '#00a0e1ff',
51+
'HPHS': 'blue',
3852
'THMS': '#C04000ff',
3953
'BATS': '#41A317ff',
40-
'BEVS': '#4863A0ff'}
54+
'BEVS': '#b9c33799'}
55+
4156
commons['colors']['curtailment'] = 'red'
4257
# Hatches associated with each fuel:
43-
commons['hatches'] = {'LIG': '', 'PEA': '', 'HRD': '', 'OIL': '',
44-
'GAS': '',
45-
'NUC': '',
46-
'SUN': '',
47-
'WIN': '',
48-
'WAT': '',
49-
'BIO': '', 'GEO': '',
50-
'Storage': '', 'FlowIn': '/', 'FlowOut': '\\',
51-
'WST': '', 'OTH': '',
52-
'HDAM': '','HPHS': '','THMS': '','BATS': '','BEVS': ''
58+
commons['hatches'] = {'LIG': '', 'PEA': '', 'HRD': '', 'OIL': '', 'GAS': '', 'NUC': '', 'SUN': '', 'WIN': '', 'WAT': '',
59+
'BIO': '', 'GEO': '', 'Storage': '', 'WST': '', 'OTH': '',
60+
'FlowIn': '/', 'FlowOut': '\\', 'HDAM': '/','HPHS': '/','THMS': '','BATS': '/','BEVS': '/'
5361
}
5462

5563
commons['logfile'] = str(datetime.datetime.now()).replace(':','-').replace(' ','_') + '.dispa.log'

dispaset/postprocessing/plot.py

+55-25
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ def plot_dispatch(demand, plotdata, level=None, curtailment=None, shedload=None,
1818
1919
:param demand: Pandas Series with the demand curve
2020
:param plotdata: Pandas Dataframe with the data to be plotted. Negative columns should be at the beginning. Output of the function GetPlotData
21-
:param level: Optional pandas series with an aggregated reservoir level for the considered zone.
21+
:param level: Optional pandas series/dataframe with an (dis)aggregated reservoir level for the considered zone.
2222
:param curtailment: Optional pandas series with the value of the curtailment
2323
:param shedload: Optional pandas series with the value of the shed load
2424
:param rng: Indexes of the values to be plotted. If undefined, the first week is plotted
@@ -75,22 +75,50 @@ def plot_dispatch(demand, plotdata, level=None, curtailment=None, shedload=None,
7575

7676
fig.suptitle('Power dispatch for zone ' + demand.name[1])
7777

78+
# Define labels, patches and colors
7879
labels = []
7980
patches = []
8081
colorlist = []
8182

82-
# # Plot negative values:
83+
# Plot reservoir levels (either separated or as one value)
84+
if level is not None:
85+
if isinstance(level, pd.DataFrame):
86+
cols_lvl = level.columns.tolist()
87+
sumplot_lev = level[cols_lvl[0:]].cumsum(axis=1)
88+
sumplot_lev['zero'] = 0
89+
sumplot_lev = sumplot_lev[['zero'] + sumplot_lev.columns[:-1].tolist()]
90+
print('Its dataframe')
91+
for j in range(len(sumplot_lev.columns) - 1):
92+
col3 = sumplot_lev.columns[j]
93+
col4 = sumplot_lev.columns[j + 1]
94+
rez_color = commons['colors'][col4]
95+
rez_hatch = commons['hatches'][col4]
96+
axes[1].fill_between(pdrng, sumplot_lev.loc[pdrng, col3], sumplot_lev.loc[pdrng, col4],
97+
facecolor=rez_color, alpha=alpha, hatch=rez_hatch)
98+
labels.append(col4)
99+
patches.append(mpatches.Patch(facecolor=rez_color, alpha=alpha, hatch=rez_hatch, label=col4))
100+
colorlist.append(rez_color)
101+
elif isinstance(level, pd.Series):
102+
# Create right axis:
103+
axes[1].plot(pdrng, level[pdrng], color='k', alpha=alpha, linestyle=':')
104+
axes[1].fill_between(pdrng, 0, level[pdrng],
105+
facecolor=commons['colors']['WAT'], alpha=.3)
106+
axes[1].set_ylabel('Level [TWh]')
107+
axes[1].yaxis.label.set_fontsize(12)
108+
line_SOC = mlines.Line2D([], [], color='black', alpha=alpha, label='Reservoir', linestyle=':')
109+
110+
# Plot negative values:
83111
for j in range(idx_zero):
84112
col1 = sumplot_neg.columns[j]
85113
col2 = sumplot_neg.columns[j + 1]
86114
color = commons['colors'][col2]
87115
hatch = commons['hatches'][col2]
88116
axes[0].fill_between(pdrng, sumplot_neg.loc[pdrng, col1], sumplot_neg.loc[pdrng, col2], facecolor=color,
89-
alpha=alpha,
90-
hatch=hatch)
91-
labels.append(col1)
92-
patches.append(mpatches.Patch(facecolor=color, alpha=alpha, hatch=hatch, label=col2))
93-
colorlist.append(color)
117+
alpha=alpha, hatch=hatch)
118+
if col2 not in labels:
119+
labels.append(col1)
120+
patches.append(mpatches.Patch(facecolor=color, alpha=alpha, hatch=hatch, label=col2))
121+
colorlist.append(color)
94122

95123
# Plot Positive values:
96124
for j in range(len(sumplot_pos.columns) - 1):
@@ -118,16 +146,6 @@ def plot_dispatch(demand, plotdata, level=None, curtailment=None, shedload=None,
118146
axes[0].set_ylabel('Power [GW]')
119147
axes[0].yaxis.label.set_fontsize(12)
120148

121-
if level is not None:
122-
# Create right axis:
123-
axes[1].plot(pdrng, level[pdrng], color='k', alpha=alpha, linestyle=':')
124-
axes[1].fill_between(pdrng, 0, level[pdrng],
125-
facecolor=commons['colors']['WAT'], alpha=.3)
126-
127-
axes[1].set_ylabel('Level [TWh]')
128-
axes[1].yaxis.label.set_fontsize(12)
129-
line_SOC = mlines.Line2D([], [], color='black', alpha=alpha, label='Reservoir', linestyle=':')
130-
131149
if isinstance(shedload, pd.Series):
132150
if not shedload.index.equals(demand.index):
133151
logging.error('The shedload time series must have the same index as the demand')
@@ -296,7 +314,7 @@ def plot_zone_capacities(inputs, plot=True):
296314
PowerCapacity = PowerCapacity[cols]
297315
if plot:
298316
colors = [commons['colors'][tech] for tech in PowerCapacity.columns]
299-
ax = PowerCapacity.plot(kind="bar", figsize=(12, 8), stacked=True, color=colors, alpha=1.0, legend='reverse',
317+
ax = PowerCapacity.plot(kind="bar", figsize=(12, 8), stacked=True, color=colors, alpha=0.8, legend='reverse',
300318
title='Installed capacity per zone (the horizontal lines indicate the peak demand)')
301319
ax.set_ylabel('Capacity [MW]')
302320
demand = inputs['param_df']['Demand']['DA'].max()
@@ -326,10 +344,22 @@ def plot_zone(inputs, results, z='', rng=None, rug_plot=True):
326344

327345
plotdata = get_plot_data(inputs, results, z) / 1000 # GW
328346

347+
aggregation = False
329348
if 'OutputStorageLevel' in results:
330-
levels = filter_by_zone(results['OutputStorageLevel'], inputs, z) / 1E6 # TWh
331-
level = filter_by_storage(levels, inputs, StorageSubset='s')
332-
level = level.sum(axis=1)
349+
lev = filter_by_zone(results['OutputStorageLevel'], inputs, z) / 1E6 # TWh
350+
level = filter_by_storage(lev, inputs, StorageSubset='s')
351+
levels = pd.DataFrame(index=results['OutputStorageLevel'].index,columns=inputs['sets']['t'])
352+
for t in ['HDAM','HPHS','BEVS','BATS']:
353+
temp = filter_by_tech(level,inputs,t)
354+
levels[t] = temp.sum(axis=1)
355+
levels.dropna(axis=1,inplace=True)
356+
for col in levels.columns:
357+
if levels[col].max() == 0 and levels[col].min() == 0:
358+
del levels[col]
359+
if aggregation is True:
360+
level = level.sum(axis=1)
361+
else:
362+
level = levels
333363
else:
334364
level = pd.Series(0, index=results['OutputPower'].index)
335365

@@ -358,14 +388,14 @@ def plot_zone(inputs, results, z='', rng=None, rug_plot=True):
358388
if 'OutputCurtailedPower' in results and z in results['OutputCurtailedPower'] \
359389
and 'OutputShedLoad' in results and z in results['OutputShedLoad']:
360390
curtailment = results['OutputCurtailedPower'][z] / 1000 # GW
361-
plot_dispatch(demand, plotdata, level, curtailment=curtailment, shedload = shed_load, rng=rng)
391+
plot_dispatch(demand, plotdata, level, curtailment=curtailment, shedload = shed_load, rng=rng, alpha=0.8)
362392
elif 'OutputCurtailedPower' in results and z in results['OutputCurtailedPower']:
363393
curtailment = results['OutputCurtailedPower'][z] / 1000 # GW
364-
plot_dispatch(demand, plotdata, level, curtailment=curtailment, rng=rng)
394+
plot_dispatch(demand, plotdata, level, curtailment=curtailment, rng=rng, alpha=0.8)
365395
elif 'OutputShedLoad' in results and z in results['OutputShedLoad']:
366-
plot_dispatch(demand, plotdata, level, shedload = shed_load, rng=rng)
396+
plot_dispatch(demand, plotdata, level, shedload = shed_load, rng=rng, alpha=0.8)
367397
else:
368-
plot_dispatch(demand, plotdata, level, rng=rng)
398+
plot_dispatch(demand, plotdata, level, rng=rng, alpha=0.8)
369399

370400
# Generation plot:
371401
if rug_plot:

0 commit comments

Comments
 (0)