Skip to content

Commit

Permalink
added timeseries plotting
Browse files Browse the repository at this point in the history
  • Loading branch information
LukasFrankenQ committed Jul 22, 2023
1 parent 8567e7c commit b59ad46
Show file tree
Hide file tree
Showing 4 changed files with 209 additions and 5 deletions.
8 changes: 5 additions & 3 deletions config/config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,10 @@ scenario:
gb_regions:
- 'eso' # regions can be 'eso' zones (emphasizing grid conjestion), or 'dno'
fes_scenario: # Future energy scenario considered, can be
- 'CT'
- 'LW'
# - 'CT'
# - 'LW'
- 'FS'
- 'ST'
# - 'ST'
# FS: Falling Short,
# LW: Leading the Way,
# ST: System Transformation,
Expand Down Expand Up @@ -737,6 +737,8 @@ plotting:
energy_max: 20000
energy_min: -20000
energy_threshold: 50.
timeseries_freq: d
timeseries_month: 1
vre_techs:
- onwind
- offwind-ac
Expand Down
26 changes: 26 additions & 0 deletions rules/postprocess.smk
Original file line number Diff line number Diff line change
Expand Up @@ -138,3 +138,29 @@ rule plot_summary:
"../envs/environment.yaml"
script:
"../scripts/plot_summary.py"


rule plot_timeseries:
params:
RDIR=RDIR,
input:
network=RESULTS + "networks/elec_s{simpl}_{gb_regions}_ec_l{ll}_{opts}_{fes_scenario}_{planning_horizons}.nc",
overrides="data/override_component_attrs",
output:
timeseries_gb_year=RESULTS + "graphs/timeseries-year-gb_s{simpl}_{gb_regions}_ec_l{ll}_{opts}_{fes_scenario}_{planning_horizons}.pdf",
timeseries_gb_short=RESULTS + "graphs/timeseries-short-gb_s{simpl}_{gb_regions}_ec_l{ll}_{opts}_{fes_scenario}_{planning_horizons}.pdf",
timeseries_scotland_year=RESULTS + "graphs/timeseries-year-scotland_s{simpl}_{gb_regions}_ec_l{ll}_{opts}_{fes_scenario}_{planning_horizons}.pdf",
timeseries_scotland_short=RESULTS + "graphs/timeseries-short-scotland_s{simpl}_{gb_regions}_ec_l{ll}_{opts}_{fes_scenario}_{planning_horizons}.pdf",
timeseries_england_year=RESULTS + "graphs/timeseries-year-england_s{simpl}_{gb_regions}_ec_l{ll}_{opts}_{fes_scenario}_{planning_horizons}.pdf",
timeseries_england_short=RESULTS + "graphs/timeseries-short-england_s{simpl}_{gb_regions}_ec_l{ll}_{opts}_{fes_scenario}_{planning_horizons}.pdf",
threads: 1
resources:
mem_mb=10000,
log:
LOGS + "plot_timeseries_s{simpl}_{gb_regions}_ec_l{ll}_{opts}_{fes_scenario}_{planning_horizons}.log",
benchmark:
BENCHMARKS + "plot_timeseries_s{simpl}_{gb_regions}_ec_l{ll}_{opts}_{fes_scenario}_{planning_horizons}"
conda:
"../envs/environment.yaml"
script:
"../scripts/plot_timeseries.py"
163 changes: 163 additions & 0 deletions scripts/plot_timeseries.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@

import logging

logger = logging.getLogger(__name__)

import pandas as pd
import matplotlib.pyplot as plt
import pypsa

from _helpers import override_component_attrs
from make_summary import assign_carriers, assign_locations



if __name__ == "__main__":
if "snakemake" not in globals():
from _helpers import mock_snakemake

snakemake = mock_snakemake("plot_timeseries")

tech_colors = snakemake.config["plotting"]["tech_colors"]
tech_colors["wind"] = tech_colors["onwind"]
tech_colors["H2 dispatch"] = tech_colors["H2 Fuel Cell"]
tech_colors["H2 charge"] = tech_colors["H2 Electrolysis"]
tech_colors["battery dispatch"] = tech_colors["battery"]
tech_colors["battery charge"] = tech_colors["BEV charger"]
tech_colors["DC"] = tech_colors["HVDC links"]

overrides = override_component_attrs(snakemake.input.overrides)
n = pypsa.Network(snakemake.input.network, override_component_attrs=overrides)

assign_carriers(n)
assign_locations(n)

freq = snakemake.config["plotting"]["timeseries_freq"]
month = snakemake.config["plotting"]["timeseries_month"]

target_files = ["gb", "scotland", "england"]
bus_names = ["all", "GB0 Z5", "GB0 Z11"]

template = "timeseries_{}_{}"

for buses, target in zip(bus_names, target_files):

if buses == "all":
buses = pd.Index(n.buses.location.unique())
buses = buses[buses.str.contains("GB")]

else:
buses = pd.Index([buses])

load = n.loads_t.p_set.loc[:, buses].sum(axis=1)
inflow = pd.DataFrame(index=n.snapshots)
outflow = pd.DataFrame(index=n.snapshots)

print(n.links_t.p0.sum())
n.links_t.p0.to_csv("p0.csv")
print(n.links_t.p1.sum())
n.links_t.p1.to_csv("p0.csv")
n.generators.to_csv("genz_after.csv")

for c in n.iterate_components(n.one_port_components | n.branch_components):

print(c.name)

if c.name == "Load":
continue


if c.name in ["Generator", "StorageUnit"]:
idx = c.df.loc[c.df.bus.isin(buses)].index

c_energies = (
c.pnl.p
.loc[:, idx]
.multiply(n.snapshot_weightings.generators, axis=0)
)

for carrier in c.df.loc[idx, "carrier"].unique():
cols = c.df.loc[idx].loc[c.df.loc[idx, "carrier"] == carrier].index

inflow[carrier] = c_energies.loc[:, cols].sum(axis=1)

elif c.name == "Link":

idx_in = c.df.loc[c.df.bus1.isin(buses)].index
c_energies = c.pnl.p0.loc[:, idx_in].multiply(c.df.loc[idx_in, "efficiency"], axis=1)

for carrier in c.df.loc[idx_in, "carrier"].unique():

cols = c.df.loc[idx_in].loc[c.df.loc[idx_in, "carrier"] == carrier].index
if carrier in ["OCGT", "CCGT"]:
print(carrier)
print(c_energies.loc[:, cols].sum().rename(carrier))

inflow[carrier] = (
c_energies
.loc[:, cols]
.sum(axis=1)
)

idx_out = c.df.loc[c.df.bus0.isin(buses)].index
c_energies = c.pnl.p1.loc[:, idx_out].multiply(c.df.loc[idx_out, "efficiency"], axis=1)

for carrier in c.df.loc[idx_out, "carrier"].unique():
cols = c.df.loc[idx_out].loc[c.df.loc[idx_out, "carrier"] == carrier].index

outflow[carrier] = c_energies.loc[:, cols].sum(axis=1)


print(inflow.head())


total = (
(inflow.drop(columns="load").sum(axis=1) + outflow.sum(axis=1) - load)
.resample(freq).mean()
)


from plot_gb_validation import stackplot_to_ax

fig, ax = plt.subplots(1, 1, figsize=(16, 4))

stackplot_to_ax(
inflow.resample(freq).mean().drop(columns="load"),
ax=ax,
color_mapper=tech_colors,
)

if not outflow.empty:
stackplot_to_ax(
outflow.resample(freq).mean(),
ax=ax,
color_mapper=tech_colors,
)

ax.plot(total.index,
total,
color="black",
label="Kirchhoff Check",
linestyle="--",
)


# ax.set_title(f"{c.name} {target} {buses}")
ax.legend()

print("saving at")
print(snakemake.output[0])
# plt.savefig(snakemake.output[0])
plt.savefig('results/testfifth.pdf')

plt.show()


break







17 changes: 15 additions & 2 deletions scripts/prepare_network.py
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,7 @@ def remove_elec_base_techs(n):
for c in n.iterate_components(snakemake.config["pypsa_eur"]):
to_keep = snakemake.config["pypsa_eur"][c.name]
to_remove = pd.Index(c.df.carrier.unique()).symmetric_difference(to_keep)
to_remove = to_remove[to_remove.str.contains("GB0")]
if to_remove.empty:
continue
logger.info(f"Removing {c.list_name} with carrier {list(to_remove)}")
Expand Down Expand Up @@ -346,10 +347,15 @@ def convert_generators_to_links(n, costs):
f"GB_{carrier}",
bus=f"GB_{carrier}_bus",
carrier=carrier,
p_nom_extendable=True,
p_nom=np.inf,
marginal_cost=costs.at[carrier, "fuel"],
)
print("================================================")
print("marginal_cost of fuel:")
print(costs.at[carrier, "fuel"])
print("================================================")

logger.warning("Currently no co2 tracking in link-generators")
n.madd(
"Link",
gens.index,
Expand All @@ -373,8 +379,15 @@ def convert_generators_to_links(n, costs):
"'coal', 'lignite', 'CCGT', 'OCGT' being in config[`pypsa_eur`]"
))

def diff(li1, li2):
return (list(list(set(li1)-set(li2)) + list(set(li2)-set(li1))))

before = n.generators.index.tolist()
remove_elec_base_techs(n)

print("removed generators")
print(diff(before, n.generators.index.tolist()))


# adapted from `add_heat` method in `scripts/prepare_sector_network.py`
def add_heat_pump_load(
Expand Down Expand Up @@ -618,6 +631,7 @@ def add_gb_co2_tracking(n):
"Store",
"gb co2 stored",
e_nom_extendable=True,
e_nom_min=-1.,
carrier="co2",
bus="gb co2 stored",
)
Expand Down Expand Up @@ -688,7 +702,6 @@ def add_dac(n, costs):
scale_generation_capacity(n, snakemake.input.capacity_constraints)
convert_generators_to_links(n, other_costs)


logger.warning("Implemented unelegant clean-up of generator marginal costs")
if 'GB0 Z11 coal' in n.generators_t.marginal_cost.columns:
n.generators_t.marginal_cost.drop(columns=[
Expand Down

0 comments on commit b59ad46

Please sign in to comment.