Plot summary; take account of snapshot weightings correctly
This commit is contained in:
parent
f3a12e7aee
commit
540985164f
128
config.yaml
128
config.yaml
@ -180,6 +180,13 @@ plotting:
|
|||||||
linewidth_factor: 3.e+3 # 1.e+3 #3.e+3
|
linewidth_factor: 3.e+3 # 1.e+3 #3.e+3
|
||||||
|
|
||||||
costs_max: 800
|
costs_max: 800
|
||||||
|
costs_threshold: 1
|
||||||
|
|
||||||
|
|
||||||
|
energy_max: 15000.
|
||||||
|
energy_min: -10000.
|
||||||
|
energy_threshold: 50.
|
||||||
|
|
||||||
|
|
||||||
vre_techs: ["onwind", "offwind", "solar", "ror"]
|
vre_techs: ["onwind", "offwind", "solar", "ror"]
|
||||||
conv_techs: ["OCGT", "CCGT", "Nuclear", "Coal"]
|
conv_techs: ["OCGT", "CCGT", "Nuclear", "Coal"]
|
||||||
@ -193,60 +200,73 @@ plotting:
|
|||||||
"central CHP electric", "central gas boiler"]
|
"central CHP electric", "central gas boiler"]
|
||||||
heat_generators: ["gas boiler", "central gas boiler", "solar thermal collector", "central solar thermal collector"]
|
heat_generators: ["gas boiler", "central gas boiler", "solar thermal collector", "central solar thermal collector"]
|
||||||
tech_colors:
|
tech_colors:
|
||||||
onwind: "xkcd:azure"
|
"onwind" : "b"
|
||||||
offwind: "blue"
|
"onshore wind" : "b"
|
||||||
hydro: "g"
|
'offwind' : "c"
|
||||||
ror: "lightgreen"
|
'offshore wind' : "c"
|
||||||
PHS: "g"
|
"hydro" : "#3B5323"
|
||||||
hydro+PHS: "g"
|
"hydro reservoir" : "#3B5323"
|
||||||
solar: "yellow"
|
"ror" : "#78AB46"
|
||||||
OCGT: "brown"
|
"run of river" : "#78AB46"
|
||||||
OCGT marginal: "sandybrown"
|
'hydroelectricity' : '#006400'
|
||||||
OCGT-heat: "orange"
|
'solar' : "y"
|
||||||
central gas boiler: "orange"
|
'solar PV' : "y"
|
||||||
gas boiler: "orange"
|
'solar thermal' : 'coral'
|
||||||
gas boilers: "orange"
|
"OCGT" : "wheat"
|
||||||
gas boiler marginal: "orange"
|
"OCGT marginal" : "sandybrown"
|
||||||
gas: "brown"
|
"OCGT-heat" : "orange"
|
||||||
lines: "k"
|
"gas boiler" : "orange"
|
||||||
AC line: "k"
|
"gas boilers" : "orange"
|
||||||
AC-AC: "k"
|
"gas boiler marginal" : "orange"
|
||||||
transmission lines: "k"
|
"gas" : "brown"
|
||||||
H2: "m"
|
"natural gas" : "brown"
|
||||||
hydrogen storage: "m"
|
"lines" : "k"
|
||||||
battery: "slategray"
|
"transmission lines" : "k"
|
||||||
battery storage: "slategray"
|
"H2" : "m"
|
||||||
CAES: "lightgray"
|
"hydrogen storage" : "m"
|
||||||
nuclear: "r"
|
"battery" : "slategray"
|
||||||
nuclear marginal: "r"
|
"battery storage" : "slategray"
|
||||||
coal: "k"
|
"Nuclear" : "r"
|
||||||
coal marginal: "k"
|
"Nuclear marginal" : "r"
|
||||||
lignite: "grey"
|
"Coal" : "k"
|
||||||
lignite marginal: "grey"
|
"Coal marginal" : "k"
|
||||||
CCGT: "orange"
|
"Lignite" : "grey"
|
||||||
CCGT marginal: "orange"
|
"Lignite marginal" : "grey"
|
||||||
diesel: "darkred"
|
"CCGT" : "orange"
|
||||||
diesel marginal: "darkred"
|
"CCGT marginal" : "orange"
|
||||||
heat pumps: "green"
|
"heat pumps" : "#76EE00"
|
||||||
heat pump: "green"
|
"heat pump" : "#76EE00"
|
||||||
central heat pump: "green"
|
"air heat pump" : "#76EE00"
|
||||||
resistive heater: "pink"
|
"ground heat pump" : "#40AA00"
|
||||||
central resistive heater: "pink"
|
"resistive heater" : "pink"
|
||||||
Sabatier: "turquoise"
|
"Sabatier" : "#FF1493"
|
||||||
water tanks: "w"
|
"methanation" : "#FF1493"
|
||||||
CHP: "r"
|
"helmeth" : "#7D0552"
|
||||||
CHP heat: "r"
|
"helmeth" : "#7D0552"
|
||||||
CHP electric: "r"
|
"DAC" : "#E74C3C"
|
||||||
central CHP heat: "r"
|
"nuclear" : "#303030"
|
||||||
central CHP electric: "r"
|
"water tanks" : "#BBBBBB"
|
||||||
Pumped storage: "g"
|
"hot water storage" : "#BBBBBB"
|
||||||
Ambient: "k"
|
"hot water charging" : "#BBBBBB"
|
||||||
AC load: "b"
|
"hot water discharging" : "#999999"
|
||||||
Heat load: "r"
|
"CHP" : "r"
|
||||||
Li ion load: "grey"
|
"CHP heat" : "r"
|
||||||
heat: "r"
|
"CHP electric" : "r"
|
||||||
Li ion: "grey"
|
"PHS" : "g"
|
||||||
district heating: "#CC4E5C"
|
"Ambient" : "k"
|
||||||
|
"Electric load" : "b"
|
||||||
|
"Heat load" : "r"
|
||||||
|
"Transport load" : "grey"
|
||||||
|
"heat" : "r"
|
||||||
|
"Li ion" : "grey"
|
||||||
|
"district heating" : "#CC4E5C"
|
||||||
|
"retrofitting" : "purple"
|
||||||
|
"building retrofitting" : "purple"
|
||||||
|
"BEV charger" : "grey"
|
||||||
|
"V2G" : "grey"
|
||||||
|
"transport" : "grey"
|
||||||
|
"electricity" : "k"
|
||||||
|
"transport fuel cell" : "#AAAAAA"
|
||||||
nice_names:
|
nice_names:
|
||||||
# OCGT: "Gas"
|
# OCGT: "Gas"
|
||||||
# OCGT marginal: "Gas (marginal)"
|
# OCGT marginal: "Gas (marginal)"
|
||||||
|
@ -50,15 +50,15 @@ def calculate_costs(n,label,costs):
|
|||||||
costs.loc[idx[c.list_name,"capital",list(capital_costs_grouped.index)],label] = capital_costs_grouped.values
|
costs.loc[idx[c.list_name,"capital",list(capital_costs_grouped.index)],label] = capital_costs_grouped.values
|
||||||
|
|
||||||
if c.name == "Link":
|
if c.name == "Link":
|
||||||
p = c.pnl.p0.sum()
|
p = c.pnl.p0.multiply(n.snapshot_weightings,axis=0).sum()
|
||||||
elif c.name == "Line":
|
elif c.name == "Line":
|
||||||
continue
|
continue
|
||||||
elif c.name == "StorageUnit":
|
elif c.name == "StorageUnit":
|
||||||
p_all = c.pnl.p.copy()
|
p_all = c.pnl.p.multiply(n.snapshot_weightings,axis=0)
|
||||||
p_all[p_all < 0.] = 0.
|
p_all[p_all < 0.] = 0.
|
||||||
p = p_all.sum()
|
p = p_all.sum()
|
||||||
else:
|
else:
|
||||||
p = c.pnl.p.sum()
|
p = c.pnl.p.multiply(n.snapshot_weightings,axis=0).sum()
|
||||||
|
|
||||||
marginal_costs = p*c.df.marginal_cost
|
marginal_costs = p*c.df.marginal_cost
|
||||||
|
|
||||||
@ -97,9 +97,9 @@ def calculate_energy(n,label,energy):
|
|||||||
for c in n.iterate_components(n.one_port_components|n.branch_components):
|
for c in n.iterate_components(n.one_port_components|n.branch_components):
|
||||||
|
|
||||||
if c.name in n.one_port_components:
|
if c.name in n.one_port_components:
|
||||||
c_energies = c.pnl.p.sum().multiply(c.df.sign).groupby(c.df.carrier).sum()
|
c_energies = c.pnl.p.multiply(n.snapshot_weightings,axis=0).sum().multiply(c.df.sign).groupby(c.df.carrier).sum()
|
||||||
else:
|
else:
|
||||||
c_energies = (-c.pnl.p1.sum() - c.pnl.p0.sum()).groupby(c.df.carrier).sum()
|
c_energies = (-c.pnl.p1.multiply(n.snapshot_weightings,axis=0).sum() - c.pnl.p0.multiply(n.snapshot_weightings,axis=0).sum()).groupby(c.df.carrier).sum()
|
||||||
|
|
||||||
energy = energy.reindex(energy.index|pd.MultiIndex.from_product([[c.list_name],c_energies.index]))
|
energy = energy.reindex(energy.index|pd.MultiIndex.from_product([[c.list_name],c_energies.index]))
|
||||||
|
|
||||||
|
185
scripts/plot_summary.py
Normal file
185
scripts/plot_summary.py
Normal file
@ -0,0 +1,185 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
import pandas as pd
|
||||||
|
|
||||||
|
#allow plotting without Xwindows
|
||||||
|
import matplotlib
|
||||||
|
matplotlib.use('Agg')
|
||||||
|
|
||||||
|
import matplotlib.pyplot as plt
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#consolidate and rename
|
||||||
|
def rename_techs(label):
|
||||||
|
if label[:8] == "central ":
|
||||||
|
label = label[8:]
|
||||||
|
if label[:6] == "urban ":
|
||||||
|
label = label[6:]
|
||||||
|
|
||||||
|
if "retrofitting" in label:
|
||||||
|
label = "building retrofitting"
|
||||||
|
if "H2" in label:
|
||||||
|
label = "hydrogen storage"
|
||||||
|
if "CHP" in label:
|
||||||
|
label = "CHP"
|
||||||
|
if "water tank" in label:
|
||||||
|
label = "water tanks"
|
||||||
|
if label=="water tanks":
|
||||||
|
label = "hot water storage"
|
||||||
|
if "gas" in label and label != "gas boiler":
|
||||||
|
label = "natural gas"
|
||||||
|
if "solar thermal" in label:
|
||||||
|
label = "solar thermal"
|
||||||
|
if label == "solar":
|
||||||
|
label = "solar PV"
|
||||||
|
if label == "heat pump":
|
||||||
|
label = "air heat pump"
|
||||||
|
if label == "Sabatier":
|
||||||
|
label = "methanation"
|
||||||
|
if label == "offwind":
|
||||||
|
label = "offshore wind"
|
||||||
|
if label == "onwind":
|
||||||
|
label = "onshore wind"
|
||||||
|
if label == "ror":
|
||||||
|
label = "hydroelectricity"
|
||||||
|
if label == "hydro":
|
||||||
|
label = "hydroelectricity"
|
||||||
|
if label == "PHS":
|
||||||
|
label = "hydroelectricity"
|
||||||
|
if label == "co2 Store":
|
||||||
|
label = "DAC"
|
||||||
|
if "battery" in label:
|
||||||
|
label = "battery storage"
|
||||||
|
|
||||||
|
return label
|
||||||
|
|
||||||
|
|
||||||
|
preferred_order = pd.Index(["transmission lines","hydroelectricity","hydro reservoir","run of river","pumped hydro storage","onshore wind","offshore wind","solar PV","solar thermal","building retrofitting","ground heat pump","air heat pump","resistive heater","CHP","OCGT","gas boiler","gas","natural gas","methanation","hydrogen storage","battery storage","hot water storage"])
|
||||||
|
|
||||||
|
def plot_costs():
|
||||||
|
|
||||||
|
|
||||||
|
cost_df = pd.read_csv(snakemake.input.costs,index_col=list(range(3)),header=[0,1,2])
|
||||||
|
|
||||||
|
|
||||||
|
df = cost_df.groupby(cost_df.index.get_level_values(2)).sum()
|
||||||
|
|
||||||
|
#convert to billions
|
||||||
|
df = df/1e9
|
||||||
|
|
||||||
|
df = df.groupby(df.index.map(rename_techs)).sum()
|
||||||
|
|
||||||
|
to_drop = df.index[df.max(axis=1) < snakemake.config['plotting']['costs_threshold']]
|
||||||
|
|
||||||
|
print("dropping")
|
||||||
|
|
||||||
|
print(df.loc[to_drop])
|
||||||
|
|
||||||
|
df = df.drop(to_drop)
|
||||||
|
|
||||||
|
print(df.sum())
|
||||||
|
|
||||||
|
new_index = (preferred_order&df.index).append(df.index.difference(preferred_order))
|
||||||
|
|
||||||
|
new_columns = df.sum().sort_values().index
|
||||||
|
|
||||||
|
fig, ax = plt.subplots()
|
||||||
|
fig.set_size_inches((12,8))
|
||||||
|
|
||||||
|
df.loc[new_index,new_columns].T.plot(kind="bar",ax=ax,stacked=True,color=[snakemake.config['plotting']['tech_colors'][i] for i in new_index])
|
||||||
|
|
||||||
|
|
||||||
|
handles,labels = ax.get_legend_handles_labels()
|
||||||
|
|
||||||
|
handles.reverse()
|
||||||
|
labels.reverse()
|
||||||
|
|
||||||
|
ax.set_ylim([0,snakemake.config['plotting']['costs_max']])
|
||||||
|
|
||||||
|
ax.set_ylabel("System Cost [EUR billion per year]")
|
||||||
|
|
||||||
|
ax.set_xlabel("")
|
||||||
|
|
||||||
|
ax.grid(axis="y")
|
||||||
|
|
||||||
|
ax.legend(handles,labels,ncol=4,loc="upper left")
|
||||||
|
|
||||||
|
|
||||||
|
fig.tight_layout()
|
||||||
|
|
||||||
|
fig.savefig(snakemake.output.costs,transparent=True)
|
||||||
|
|
||||||
|
|
||||||
|
def plot_energy():
|
||||||
|
|
||||||
|
energy_df = pd.read_csv(snakemake.input.energy,index_col=list(range(2)),header=[0,1,2])
|
||||||
|
|
||||||
|
df = energy_df.groupby(energy_df.index.get_level_values(1)).sum()
|
||||||
|
|
||||||
|
#convert MWh to TWh
|
||||||
|
df = df/1e6
|
||||||
|
|
||||||
|
df = df.groupby(df.index.map(rename_techs)).sum()
|
||||||
|
|
||||||
|
to_drop = df.index[df.abs().max(axis=1) < snakemake.config['plotting']['energy_threshold']]
|
||||||
|
|
||||||
|
print("dropping")
|
||||||
|
|
||||||
|
print(df.loc[to_drop])
|
||||||
|
|
||||||
|
df = df.drop(to_drop)
|
||||||
|
|
||||||
|
print(df.sum())
|
||||||
|
|
||||||
|
new_index = (preferred_order&df.index).append(df.index.difference(preferred_order))
|
||||||
|
|
||||||
|
new_columns = df.columns.sort_values()
|
||||||
|
|
||||||
|
fig, ax = plt.subplots()
|
||||||
|
fig.set_size_inches((12,8))
|
||||||
|
|
||||||
|
df.loc[new_index,new_columns].T.plot(kind="bar",ax=ax,stacked=True,color=[snakemake.config['plotting']['tech_colors'][i] for i in new_index])
|
||||||
|
|
||||||
|
|
||||||
|
handles,labels = ax.get_legend_handles_labels()
|
||||||
|
|
||||||
|
handles.reverse()
|
||||||
|
labels.reverse()
|
||||||
|
|
||||||
|
ax.set_ylim([snakemake.config['plotting']['energy_min'],snakemake.config['plotting']['energy_max']])
|
||||||
|
|
||||||
|
ax.set_ylabel("Energy [TWh/a]")
|
||||||
|
|
||||||
|
ax.set_xlabel("")
|
||||||
|
|
||||||
|
ax.grid(axis="y")
|
||||||
|
|
||||||
|
ax.legend(handles,labels,ncol=4,loc="upper left")
|
||||||
|
|
||||||
|
|
||||||
|
fig.tight_layout()
|
||||||
|
|
||||||
|
fig.savefig(snakemake.output.energy,transparent=True)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
# Detect running outside of snakemake and mock snakemake for testing
|
||||||
|
if 'snakemake' not in globals():
|
||||||
|
from vresutils import Dict
|
||||||
|
import yaml
|
||||||
|
snakemake = Dict()
|
||||||
|
with open('config.yaml') as f:
|
||||||
|
snakemake.config = yaml.load(f)
|
||||||
|
snakemake.input = Dict()
|
||||||
|
snakemake.output = Dict()
|
||||||
|
name = "37-lv"
|
||||||
|
|
||||||
|
for item in ["costs","energy"]:
|
||||||
|
snakemake.input[item] = snakemake.config['summary_dir'] + '/{name}/csvs/{item}.csv'.format(name=name,item=item)
|
||||||
|
snakemake.output[item] = snakemake.config['summary_dir'] + '/{name}/graphs/{item}.pdf'.format(name=name,item=item)
|
||||||
|
|
||||||
|
plot_costs()
|
||||||
|
|
||||||
|
plot_energy()
|
Loading…
Reference in New Issue
Block a user