diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 273ee8f6..e8fe36cb 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -30,16 +30,18 @@ repos: rev: v2.3.0 hooks: - id: codespell - args: ['--ignore-regex="(\b[A-Z]+\b)"', '--ignore-words-list=fom,appartment,bage,ore,setis,tabacco,berfore,vor'] # Ignore capital case words, e.g. country codes + args: ['--ignore-regex="(\b[A-Z]+\b)"', '--ignore-words-list=fom,appartment,bage,ore,setis,tabacco,berfore,vor,pris'] # Ignore capital case words, e.g. country codes types_or: [python, rst, markdown] files: ^(scripts|doc)/ - # Make docstrings PEP 257 compliant -- repo: https://github.com/PyCQA/docformatter - rev: v1.7.5 - hooks: - - id: docformatter - args: ["--in-place", "--make-summary-multi-line", "--pre-summary-newline"] +# Make docstrings PEP 257 compliant +# Broken for pre-commit<=4.0.0 +# See https://github.com/PyCQA/docformatter/issues/293 +# - repo: https://github.com/PyCQA/docformatter +# rev: v1.7.5 +# hooks: +# - id: docformatter +# args: ["--in-place", "--make-summary-multi-line", "--pre-summary-newline"] - repo: https://github.com/keewis/blackdoc rev: v0.3.9 diff --git a/workflow/Snakefile b/workflow/Snakefile index a42af4b9..296cd5af 100644 --- a/workflow/Snakefile +++ b/workflow/Snakefile @@ -631,11 +631,12 @@ rule plot_ariadne_report: regions_onshore_clustered=expand( resources("regions_onshore_base_s_{clusters}.geojson"), clusters=config["scenario"]["clusters"], - allow_missing=True + allow_missing=True, ), rc="matplotlibrc", output: - elec_price_duration_curve=RESULTS + "ariadne/report/elec_price_duration_curve.png", + elec_price_duration_curve=RESULTS + + "ariadne/report/elec_price_duration_curve.png", elec_price_duration_hist=RESULTS + "ariadne/report/elec_price_duration_hist.png", results=directory(RESULTS + "ariadne/report"), elec_transmission=directory(RESULTS + "ariadne/report/elec_transmission"), @@ -646,14 +647,14 @@ rule plot_ariadne_report: resources: mem_mb=10000, log: - RESULTS - + "logs/plot_ariadne_report.log", + RESULTS + "logs/plot_ariadne_report.log", script: "scripts/plot_ariadne_report.py" + rule ariadne_report_only: input: expand( RESULTS + "ariadne/report/elec_price_duration_curve.png", run=config_provider("run", "name"), - ), \ No newline at end of file + ), diff --git a/workflow/scripts/export_ariadne_variables.py b/workflow/scripts/export_ariadne_variables.py index d780e66c..56d734dc 100644 --- a/workflow/scripts/export_ariadne_variables.py +++ b/workflow/scripts/export_ariadne_variables.py @@ -1552,7 +1552,6 @@ def get_secondary_energy(n, region, _industry_demand): total_oil_fuel_usage * oil_fractions["Efuel"] ) - try: methanol_production = ( n.statistics.supply(bus_carrier="methanol", **kwargs) @@ -1572,7 +1571,6 @@ def get_secondary_energy(n, region, _industry_demand): except KeyError: var["Secondary Energy|Methanol"] = 0 - var["Secondary Energy|Liquids|Hydrogen"] += var["Secondary Energy|Methanol"] var["Secondary Energy|Liquids|Biomass"] = ( @@ -2143,7 +2141,6 @@ def get_final_energy( + var["Final Energy|Transportation|Methanol"] ) - # var["Final Energy|Transportation|Liquids|Biomass"] = \ # var["Final Energy|Transportation|Liquids|Synthetic Fossil"] = \ var["Final Energy|Transportation|Liquids|Petroleum"] = ( @@ -2184,9 +2181,9 @@ def get_final_energy( var["Final Energy|Bunkers|Navigation|Liquids"] * oil_fractions[fraction_key] ) - var["Final Energy|Bunkers|Navigation"] = ( - var["Final Energy|Bunkers|Navigation|Liquids"] - ) + var["Final Energy|Bunkers|Navigation"] = var[ + "Final Energy|Bunkers|Navigation|Liquids" + ] # var["Final Energy|Bunkers|Navigation|Gases"] = \ # ! Not implemented @@ -3915,16 +3912,14 @@ def get_export_import_links(n, region, carriers): DE_bio_fraction = 0 else: DE_bio_fraction = ( - DE_renewable_oil.filter(like="bio").sum() - / DE_renewable_oil.sum() + DE_renewable_oil.filter(like="bio").sum() / DE_renewable_oil.sum() ) if EU_renewable_oil.sum() == 0: EU_bio_fraction = 0 else: EU_bio_fraction = ( - EU_renewable_oil.filter(like="bio").sum() - / EU_renewable_oil.sum() + EU_renewable_oil.filter(like="bio").sum() / EU_renewable_oil.sum() ) exports_oil_renew, imports_oil_renew = get_export_import_links( @@ -3932,36 +3927,31 @@ def get_export_import_links(n, region, carriers): ) var["Trade|Secondary Energy|Liquids|Biomass|Volume"] = ( - exports_oil_renew * DE_bio_fraction - - imports_oil_renew * EU_bio_fraction + exports_oil_renew * DE_bio_fraction - imports_oil_renew * EU_bio_fraction ) * MWh2PJ - + var["Trade|Secondary Energy|Liquids|Biomass|Gross Import|Volume"] = ( imports_oil_renew * EU_bio_fraction * MWh2PJ ) - exports_meoh, imports_meoh = get_export_import_links( - n, region, ["methanol"] - ) + exports_meoh, imports_meoh = get_export_import_links(n, region, ["methanol"]) var["Trade|Secondary Energy|Liquids|Hydrogen|Volume"] = ( exports_oil_renew * (1 - DE_bio_fraction) - imports_oil_renew * (1 - EU_bio_fraction) - + exports_meoh - imports_meoh + + exports_meoh + - imports_meoh ) * MWh2PJ var["Trade|Secondary Energy|Liquids|Hydrogen|Gross Import|Volume"] = ( - imports_oil_renew * (1 - EU_bio_fraction) - + imports_meoh + imports_oil_renew * (1 - EU_bio_fraction) + imports_meoh ) * MWh2PJ var["Trade|Secondary Energy|Methanol|Volume"] = ( exports_meoh - imports_meoh ) * MWh2PJ - var["Trade|Secondary Energy|Methanol|Gross Import|Volume"] = ( - imports_meoh * MWh2PJ - ) + var["Trade|Secondary Energy|Methanol|Gross Import|Volume"] = imports_meoh * MWh2PJ # Trade|Secondary Energy|Gases|Hydrogen|Volume @@ -4328,9 +4318,7 @@ def get_operational_and_capital_costs(year): def hack_DC_projects(n, model_year): logger.info(f"Hacking DC projects for year {model_year}") - logger.warning( - f"Assuming all indices of DC projects start with 'DC' or 'TYNDP'" - ) + logger.warning(f"Assuming all indices of DC projects start with 'DC' or 'TYNDP'") tprojs = n.links.loc[ (n.links.index.str.startswith("DC") | n.links.index.str.startswith("TYNDP")) & ~n.links.reversed @@ -4370,7 +4358,7 @@ def hack_DC_projects(n, model_year): # Past projects should have their p_nom_opt bigger or equal to p_nom if model_year <= 2035: assert ( - n.links.loc[past_projects, "p_nom_opt"] + 0.1 # numerical error tolerance + n.links.loc[past_projects, "p_nom_opt"] + 0.1 # numerical error tolerance >= n.links.loc[past_projects, "p_nom"] ).all() @@ -4381,10 +4369,8 @@ def hack_AC_projects(n, n_start, model_year): logger.info(f"Hacking AC projects for year {model_year}") # All transmission projects have build_year > 0, this is implicit in the query - ac_projs = n.lines.query( - "@model_year - 5 < build_year <= @model_year" - ).index - + ac_projs = n.lines.query("@model_year - 5 < build_year <= @model_year").index + s_nom_start = n_start.lines.loc[ac_projs, "s_nom"] # Eventhough the lines are available to the model from the start, @@ -4396,11 +4382,13 @@ def hack_AC_projects(n, n_start, model_year): return n + def hack_transmission_projects(n, n_start, model_year): n = hack_DC_projects(n, model_year) n = hack_AC_projects(n, n_start, model_year) return n + def get_ariadne_var( n, industry_demand, diff --git a/workflow/scripts/modify_prenetwork.py b/workflow/scripts/modify_prenetwork.py index 01adfaab..97e4db62 100644 --- a/workflow/scripts/modify_prenetwork.py +++ b/workflow/scripts/modify_prenetwork.py @@ -1134,7 +1134,7 @@ def drop_duplicate_transmission_projects(n): n.mremove("Line", to_drop) # This is a hot fix until the lines get properly removed in pypsa-eur - manual = ["TYNDP2020_1", "TYNDP2020_2", "TYNDP2020_23"] # DC3, DC4, DC1 + manual = ["TYNDP2020_1", "TYNDP2020_2", "TYNDP2020_23"] # DC3, DC4, DC1 for line in manual: if line in n.lines.index: n.remove("Line", line) diff --git a/workflow/scripts/plot_ariadne_report.py b/workflow/scripts/plot_ariadne_report.py index 6e68f9cb..882d7cd5 100644 --- a/workflow/scripts/plot_ariadne_report.py +++ b/workflow/scripts/plot_ariadne_report.py @@ -1,26 +1,26 @@ # -*- coding: utf-8 -*- +import logging import os import sys -import logging +from itertools import compress +from multiprocessing import Pool + +import cartopy.crs as ccrs +import geopandas as gpd import matplotlib.dates as mdates import matplotlib.pyplot as plt import numpy as np import pandas as pd import pypsa -import geopandas as gpd -import cartopy.crs as ccrs - from matplotlib.lines import Line2D from pypsa.plot import add_legend_lines -from itertools import compress -from multiprocessing import Pool path = "../submodules/pypsa-eur/scripts" sys.path.insert(1, os.path.abspath(path)) -from export_ariadne_variables import hack_transmission_projects from _helpers import configure_logging, set_scenario_config -from plot_summary import preferred_order, rename_techs +from export_ariadne_variables import hack_transmission_projects from plot_power_network import load_projection +from plot_summary import preferred_order, rename_techs from pypsa.plot import add_legend_circles, add_legend_lines, add_legend_patches logger = logging.getLogger(__name__) @@ -157,6 +157,7 @@ "DC", ] + ####### functions ####### def get_condense_sum(df, groups, groups_name, return_original=False): """ @@ -203,7 +204,7 @@ def plot_nodal_balance( plot_loads=True, resample=None, nice_names=False, - threshold=1e-3, # in GWh + threshold=1e-3, # in GWh condense_groups=None, condense_names=None, ): @@ -214,7 +215,7 @@ def plot_nodal_balance( end_date = end_date regions = regions period = network.generators_t.p.index[ - (network.generators_t.p.index >= start_date) + (network.generators_t.p.index >= start_date) & (network.generators_t.p.index <= end_date) ] # ToDo find out why this is overwriting itself @@ -249,7 +250,7 @@ def plot_nodal_balance( # split into df with positive and negative values df_neg, df_pos = df.clip(upper=0), df.clip(lower=0) df_pos = df_pos[df_pos.sum().sort_values(ascending=False).index] - df_neg = df_neg[df_neg.sum().sort_values().index] + df_neg = df_neg[df_neg.sum().sort_values().index] # get colors c_neg, c_pos = [tech_colors[col] for col in df_neg.columns], [ tech_colors[col] for col in df_pos.columns @@ -269,7 +270,7 @@ def plot_nodal_balance( ) # plot lmps - if plot_lmps: + if plot_lmps: lmps = network.buses_t.marginal_price[ network.buses[network.buses.carrier.isin(carriers)].index ].mean(axis=1)[period] @@ -654,12 +655,14 @@ def plot_price_duration_hist( lmps = pd.DataFrame(lmps.values.flatten()) lmps.columns = ["lmp"] - axes[i].hist(lmps, - bins=100, - color=year_colors[i], - alpha=0.5, - label=years[i], - range=x_lim_values,) + axes[i].hist( + lmps, + bins=100, + color=year_colors[i], + alpha=0.5, + label=years[i], + range=x_lim_values, + ) axes[i].legend() axes[i].set_xlabel("Electricity Price [$€/MWh_{el}$") @@ -705,10 +708,7 @@ def group_pipes(df, drop_direction=False): ) -def plot_h2_map(n, - regions, - savepath, - only_de=False): +def plot_h2_map(n, regions, savepath, only_de=False): assign_location(n) @@ -754,16 +754,12 @@ def plot_h2_map(n, if not h2_retro.empty: h2_retro = ( - group_pipes(h2_retro, drop_direction=True) - .reindex(h2_new.index) - .fillna(0) + group_pipes(h2_retro, drop_direction=True).reindex(h2_new.index).fillna(0) ) if not h2_kern.empty: h2_kern = ( - group_pipes(h2_kern, drop_direction=True) - .reindex(h2_new.index) - .fillna(0) + group_pipes(h2_kern, drop_direction=True).reindex(h2_new.index).fillna(0) ) h2_total = n.links.p_nom_opt.groupby(level=0).sum() @@ -772,18 +768,20 @@ def plot_h2_map(n, # drop all reversed pipe n.links.drop(n.links.index[n.links.index.str.contains("reversed")], inplace=True) n.links.rename(index=lambda x: x.split("-2")[0], inplace=True) - n.links = n.links.groupby(level=0).agg({ - **{col: 'first' for col in n.links.columns if col != 'p_nom_opt'}, # Take first value for all columns except 'p_nom_opt' - 'p_nom_opt': 'sum' # Sum values for 'p_nom_opt' - }) + n.links = n.links.groupby(level=0).agg( + { + **{ + col: "first" for col in n.links.columns if col != "p_nom_opt" + }, # Take first value for all columns except 'p_nom_opt' + "p_nom_opt": "sum", # Sum values for 'p_nom_opt' + } + ) link_widths_total = link_widths_total.reindex(n.links.index).fillna(0.0) link_widths_total[n.links.p_nom_opt < line_lower_threshold] = 0.0 carriers_pipe = ["H2 pipeline", "H2 pipeline retrofitted", "H2 pipeline (Kernnetz)"] - total = n.links.p_nom_opt.where( - n.links.carrier.isin(carriers_pipe), other=0.0 - ) - + total = n.links.p_nom_opt.where(n.links.carrier.isin(carriers_pipe), other=0.0) + retro = n.links.p_nom_opt.where( n.links.carrier == "H2 pipeline retrofitted", other=0.0 ) @@ -927,11 +925,7 @@ def plot_h2_map(n, fig.savefig(savepath, bbox_inches="tight") -def plot_h2_map_de(n, - regions, - tech_colors, - savepath, - specify_buses=None): +def plot_h2_map_de(n, regions, tech_colors, savepath, specify_buses=None): assign_location(n) @@ -944,7 +938,6 @@ def plot_h2_map_de(n, ) # TWh regions["H2"] = regions["H2"].where(regions["H2"] > 0.1) - linewidth_factor = 4e3 # MW below which not drawn line_lower_threshold = 0 @@ -953,35 +946,78 @@ def plot_h2_map_de(n, if specify_buses is None: bus_size_factor = 1e5 carriers = ["H2 Electrolysis", "H2 Fuel Cell"] - elec = n.links[(n.links.carrier.isin(carriers)) & (n.links.index.str.contains("DE"))].index + elec = n.links[ + (n.links.carrier.isin(carriers)) & (n.links.index.str.contains("DE")) + ].index bus_sizes = ( - n.links.loc[elec, "p_nom_opt"].groupby([n.links["bus0"], n.links.carrier]).sum() + n.links.loc[elec, "p_nom_opt"] + .groupby([n.links["bus0"], n.links.carrier]) + .sum() / bus_size_factor ) if specify_buses == "production": bus_size_factor = 2e8 - h2_producers = n.links.index[n.links.index.str.startswith("DE") & (n.links.bus1.map(n.buses.carrier) == "H2")] + h2_producers = n.links.index[ + n.links.index.str.startswith("DE") + & (n.links.bus1.map(n.buses.carrier) == "H2") + ] carriers = h2_producers.map(n.links.carrier).unique().tolist() - production = -n.links_t.p1[h2_producers].multiply(n.snapshot_weightings.generators,axis=0) - bus_sizes = production.sum().groupby( - [production.sum().index.map(n.links.bus1) , production.sum().index.map(n.links.carrier)] - ).sum() / bus_size_factor + production = -n.links_t.p1[h2_producers].multiply( + n.snapshot_weightings.generators, axis=0 + ) + bus_sizes = ( + production.sum() + .groupby( + [ + production.sum().index.map(n.links.bus1), + production.sum().index.map(n.links.carrier), + ] + ) + .sum() + / bus_size_factor + ) if specify_buses == "consumption": bus_size_factor = 2e8 # links - h2_consumers_links = n.links.index[n.links.index.str.startswith("DE") & (n.links.bus0.map(n.buses.carrier) == "H2")] - consumption_links = n.links_t.p0[h2_consumers_links].multiply(n.snapshot_weightings.generators,axis=0) - bus_sizes_links = consumption_links.sum().groupby( - [consumption_links.sum().index.map(n.links.bus0) , consumption_links.sum().index.map(n.links.carrier)] - ).sum() / bus_size_factor - #loads - h2_consumers_loads = n.loads.index[n.loads.bus.str.startswith("DE") & (n.loads.bus.map(n.buses.carrier) == "H2")] - consumption_loads = n.loads_t.p[h2_consumers_loads].multiply(n.snapshot_weightings.generators,axis=0) - bus_sizes_loads = consumption_loads.sum().groupby( - [consumption_loads.sum().index.map(n.loads.bus) , consumption_loads.sum().index.map(n.loads.carrier)] - ).sum() / bus_size_factor - + h2_consumers_links = n.links.index[ + n.links.index.str.startswith("DE") + & (n.links.bus0.map(n.buses.carrier) == "H2") + ] + consumption_links = n.links_t.p0[h2_consumers_links].multiply( + n.snapshot_weightings.generators, axis=0 + ) + bus_sizes_links = ( + consumption_links.sum() + .groupby( + [ + consumption_links.sum().index.map(n.links.bus0), + consumption_links.sum().index.map(n.links.carrier), + ] + ) + .sum() + / bus_size_factor + ) + # loads + h2_consumers_loads = n.loads.index[ + n.loads.bus.str.startswith("DE") + & (n.loads.bus.map(n.buses.carrier) == "H2") + ] + consumption_loads = n.loads_t.p[h2_consumers_loads].multiply( + n.snapshot_weightings.generators, axis=0 + ) + bus_sizes_loads = ( + consumption_loads.sum() + .groupby( + [ + consumption_loads.sum().index.map(n.loads.bus), + consumption_loads.sum().index.map(n.loads.carrier), + ] + ) + .sum() + / bus_size_factor + ) + bus_sizes = pd.concat([bus_sizes_links, bus_sizes_loads]) def rename_carriers(carrier): @@ -991,25 +1027,35 @@ def rename_carriers(carrier): return "H2 CHP" else: return carrier + bus_sizes = bus_sizes.rename(index=lambda x: rename_carriers(x), level=1) bus_sizes = bus_sizes.groupby(level=[0, 1]).sum() tech_colors["H2 CHP"] = "darkorange" # only select 4 most contributing carriers and summarise rest as other - others = (bus_sizes.groupby(level=[1]).sum() / bus_sizes.sum()).sort_values(ascending=False)[5:].index.tolist() + others = ( + (bus_sizes.groupby(level=[1]).sum() / bus_sizes.sum()) + .sort_values(ascending=False)[5:] + .index.tolist() + ) replacement_dict = {value: "other" for value in others} bus_sizes = bus_sizes.rename(index=replacement_dict, level=1) bus_sizes = bus_sizes.groupby(level=[0, 1]).sum() - carriers = bus_sizes.index.get_level_values(1).unique().tolist() - + carriers = bus_sizes.index.get_level_values(1).unique().tolist() + # make a fake MultiIndex so that area is correct for legend bus_sizes.rename(index=lambda x: x.replace(" H2", ""), level=0, inplace=True) - + # Drop non-electric buses so they don't clutter the plot n.buses.drop(n.buses.index[n.buses.carrier != "AC"], inplace=True) # drop all links which are not H2 pipelines or not in germany n.links.drop( - n.links.index[~((n.links['carrier'].str.contains("H2 pipeline")) & (n.links.index.str.contains("DE")))], - inplace=True + n.links.index[ + ~( + (n.links["carrier"].str.contains("H2 pipeline")) + & (n.links.index.str.contains("DE")) + ) + ], + inplace=True, ) h2_new = n.links[n.links.carrier == "H2 pipeline"] @@ -1021,16 +1067,12 @@ def rename_carriers(carrier): if not h2_retro.empty: h2_retro = ( - group_pipes(h2_retro, drop_direction=True) - .reindex(h2_new.index) - .fillna(0) + group_pipes(h2_retro, drop_direction=True).reindex(h2_new.index).fillna(0) ) if not h2_kern.empty: h2_kern = ( - group_pipes(h2_kern, drop_direction=True) - .reindex(h2_new.index) - .fillna(0) + group_pipes(h2_kern, drop_direction=True).reindex(h2_new.index).fillna(0) ) h2_total = n.links.p_nom_opt.groupby(level=0).sum() @@ -1039,18 +1081,20 @@ def rename_carriers(carrier): # drop all reversed pipe n.links.drop(n.links.index[n.links.index.str.contains("reversed")], inplace=True) n.links.rename(index=lambda x: x.split("-2")[0], inplace=True) - n.links = n.links.groupby(level=0).agg({ - **{col: 'first' for col in n.links.columns if col != 'p_nom_opt'}, # Take first value for all columns except 'p_nom_opt' - 'p_nom_opt': 'sum' # Sum values for 'p_nom_opt' - }) + n.links = n.links.groupby(level=0).agg( + { + **{ + col: "first" for col in n.links.columns if col != "p_nom_opt" + }, # Take first value for all columns except 'p_nom_opt' + "p_nom_opt": "sum", # Sum values for 'p_nom_opt' + } + ) link_widths_total = link_widths_total.reindex(n.links.index).fillna(0.0) link_widths_total[n.links.p_nom_opt < line_lower_threshold] = 0.0 carriers_pipe = ["H2 pipeline", "H2 pipeline retrofitted", "H2 pipeline (Kernnetz)"] - total = n.links.p_nom_opt.where( - n.links.carrier.isin(carriers_pipe), other=0.0 - ) - + total = n.links.p_nom_opt.where(n.links.carrier.isin(carriers_pipe), other=0.0) + retro = n.links.p_nom_opt.where( n.links.carrier == "H2 pipeline retrofitted", other=0.0 ) @@ -1079,7 +1123,6 @@ def rename_carriers(carrier): color_retrofit = "#499a9c" color_kern = "#6b3161" - n.plot( geomap=True, bus_sizes=bus_sizes, @@ -1209,16 +1252,18 @@ def rename_carriers(carrier): ### electricity transmission + def plot_elec_map_de( network, base_network, tech_colors, regions_de, savepath, - expansion_case = "total-expansion"): + expansion_case="total-expansion", +): m = network.copy() - m.mremove("Bus",m.buses[m.buses.x == 0].index ) + m.mremove("Bus", m.buses[m.buses.x == 0].index) m.buses.drop(m.buses.index[m.buses.carrier != "AC"], inplace=True) m_base = base_network.copy() @@ -1226,7 +1271,9 @@ def plot_elec_map_de( # storage as cmap on map battery_storage = m.stores[m.stores.carrier.isin(["battery"])] regions_de["battery"] = ( - battery_storage.rename(index=battery_storage.bus.str.replace(" battery", "").map(m.buses.location)) + battery_storage.rename( + index=battery_storage.bus.str.replace(" battery", "").map(m.buses.location) + ) .e_nom_opt.groupby(level=0) .sum() .div(1e3) @@ -1235,22 +1282,26 @@ def plot_elec_map_de( # buses bus_size_factor = 0.5e6 - carriers = ["onwind", 'offwind-ac', 'offwind-dc',"solar", 'solar-hsat'] - elec = m.generators[(m.generators.carrier.isin(carriers)) & (m.generators.bus.str.contains("DE"))].index + carriers = ["onwind", "offwind-ac", "offwind-dc", "solar", "solar-hsat"] + elec = m.generators[ + (m.generators.carrier.isin(carriers)) & (m.generators.bus.str.contains("DE")) + ].index bus_sizes = ( - m.generators.loc[elec, "p_nom_opt"].groupby([m.generators.bus, m.generators.carrier]).sum() + m.generators.loc[elec, "p_nom_opt"] + .groupby([m.generators.bus, m.generators.carrier]) + .sum() / bus_size_factor ) replacement_dict = { - "onwind" : "Onshore Wind", - "offwind-ac" : "Offshore Wind", - "offwind-dc" : "Offshore Wind", - "solar" : "Solar", - "solar-hsat" : "Solar", + "onwind": "Onshore Wind", + "offwind-ac": "Offshore Wind", + "offwind-dc": "Offshore Wind", + "solar": "Solar", + "solar-hsat": "Solar", } bus_sizes = bus_sizes.rename(index=replacement_dict, level=1) bus_sizes = bus_sizes.groupby(level=[0, 1]).sum() - carriers = bus_sizes.index.get_level_values(1).unique().tolist() + carriers = bus_sizes.index.get_level_values(1).unique().tolist() # lines linew_factor = 1e3 @@ -1291,7 +1342,7 @@ def plot_elec_map_de( regions_de = regions_de.to_crs(proj.proj4_init) fig, ax = plt.subplots(figsize=(10, 8), subplot_kw={"projection": proj}) - + m.plot( ax=ax, margin=0.06, @@ -1315,7 +1366,7 @@ def plot_elec_map_de( "extend": "max", }, ) - + # Set geographic extent for Germany ax.set_extent([5.5, 15.5, 47, 56], crs=ccrs.PlateCarree()) @@ -1340,7 +1391,7 @@ def plot_elec_map_de( patch_kw=dict(facecolor="lightgrey"), legend_kw=legend_kw, ) - + # AC sizes_ac = [10, 5] labels_ac = [f"HVAC ({s} GW)" for s in sizes_ac] @@ -1367,12 +1418,10 @@ def plot_elec_map_de( facecolor="white", ) - add_legend_lines( - ax, sizes, labels, colors = colors, legend_kw=legend_kw - ) + add_legend_lines(ax, sizes, labels, colors=colors, legend_kw=legend_kw) - colors = [tech_colors[c] for c in carriers] - labels = carriers + colors = [tech_colors[c] for c in carriers] + labels = carriers legend_kw = dict( loc="upper left", bbox_to_anchor=(0, 0.9), @@ -1385,7 +1434,6 @@ def plot_elec_map_de( fig.savefig(savepath, bbox_inches="tight") - if __name__ == "__main__": if "snakemake" not in globals(): import os @@ -1413,7 +1461,7 @@ def plot_elec_map_de( config = snakemake.config planning_horizons = snakemake.params.planning_horizons tech_colors = snakemake.params.plotting["tech_colors"] - + # define possible renaming and grouping of carriers c_g = [solar, electricity_load, electricity_imports] c_n = ["Solar", "Electricity load", "Electricity trade"] @@ -1443,18 +1491,24 @@ def plot_elec_map_de( for n, my in zip(_networks, modelyears) ] # update the tech_colors - tech_colors.update(networks[0].carriers.color.rename(networks[0].carriers.nice_name).to_dict()) + tech_colors.update( + networks[0].carriers.color.rename(networks[0].carriers.nice_name).to_dict() + ) ### plotting for year in planning_horizons: network = networks[planning_horizons.index(year)].copy() ct = "DE" buses = network.buses.index[(network.buses.index.str[:2] == ct)].drop("DE") - balance = network.statistics.energy_balance( - aggregate_time=False, - nice_names=False, - groupby=network.statistics.groupers.get_bus_and_carrier_and_bus_carrier - ).loc[:,buses,:,:].droplevel("bus") + balance = ( + network.statistics.energy_balance( + aggregate_time=False, + nice_names=False, + groupby=network.statistics.groupers.get_bus_and_carrier_and_bus_carrier, + ) + .loc[:, buses, :, :] + .droplevel("bus") + ) # electricity supply and demand plot_nodal_balance( @@ -1469,7 +1523,7 @@ def plot_elec_map_de( plot_lmps=False, plot_loads=False, nice_names=True, - threshold=1e2, # in GWh as sum over period + threshold=1e2, # in GWh as sum over period condense_groups=c_g, condense_names=c_n, ) @@ -1484,8 +1538,8 @@ def plot_elec_map_de( model_run=snakemake.wildcards.run, nice_names=True, threshold=1e2, - condense_groups= [electricity_load, electricity_imports], - condense_names= ["Electricity load", "Electricity trade"], + condense_groups=[electricity_load, electricity_imports], + condense_names=["Electricity load", "Electricity trade"], ) plot_nodal_balance( @@ -1498,8 +1552,8 @@ def plot_elec_map_de( model_run=snakemake.wildcards.run, nice_names=True, threshold=1e2, - condense_groups= [electricity_load, electricity_imports], - condense_names= ["Electricity load", "Electricity trade"], + condense_groups=[electricity_load, electricity_imports], + condense_names=["Electricity load", "Electricity trade"], ) # storage @@ -1532,28 +1586,28 @@ def plot_elec_map_de( ## hydrogen transmission map_opts = snakemake.params.plotting["map"] - snakemake.params.plotting["projection"] = { - "name": "EqualEarth" - } + snakemake.params.plotting["projection"] = {"name": "EqualEarth"} proj = load_projection(snakemake.params.plotting) regions = gpd.read_file(snakemake.input.regions_onshore_clustered).set_index("name") - + for year in planning_horizons: network = networks[planning_horizons.index(year)].copy() - plot_h2_map(network, - regions, - savepath=f"{snakemake.output.h2_transmission}/h2_transmission_all-regions_{year}.png") + plot_h2_map( + network, + regions, + savepath=f"{snakemake.output.h2_transmission}/h2_transmission_all-regions_{year}.png", + ) regions_de = regions[regions.index.str.startswith("DE")] for sb in ["production", "consumption"]: network = networks[planning_horizons.index(year)].copy() - plot_h2_map_de(network, - regions_de, - tech_colors = tech_colors, - specify_buses=sb, - savepath=f"{snakemake.output.h2_transmission}/h2_transmission_DE_{sb}_{year}.png", - ) - + plot_h2_map_de( + network, + regions_de, + tech_colors=tech_colors, + specify_buses=sb, + savepath=f"{snakemake.output.h2_transmission}/h2_transmission_DE_{sb}_{year}.png", + ) ## electricity transmission for year in planning_horizons: @@ -1567,12 +1621,11 @@ def plot_elec_map_de( regions_de, savepath=f"{snakemake.output.elec_transmission}/elec-transmission-DE-{s}-{year}.png", expansion_case=s, - ) + ) - - ## nodal balances general (might not be very robust) + ## nodal balances general (might not be very robust) plt.style.use(["bmh", snakemake.input.rc]) - + year = 2045 network = networks[planning_horizons.index(year)].copy() n = network @@ -1583,14 +1636,17 @@ def plot_elec_map_de( balance = n.statistics.energy_balance(aggregate_time=False) - # only DE + # only DE ct = "DE" buses = n.buses.index[(n.buses.index.str[:2] == ct)].drop("DE") - balance = n.statistics.energy_balance( - aggregate_time=False, - groupby=n.statistics.groupers.get_bus_and_carrier_and_bus_carrier - ).loc[:,buses,:,:].droplevel("bus") - + balance = ( + n.statistics.energy_balance( + aggregate_time=False, + groupby=n.statistics.groupers.get_bus_and_carrier_and_bus_carrier, + ) + .loc[:, buses, :, :] + .droplevel("bus") + ) n.carriers.color.update(snakemake.config["plotting"]["tech_colors"]) colors = n.carriers.color.rename(n.carriers.nice_name) @@ -1642,6 +1698,3 @@ def process_group(group, carriers, balance, months, colors): ] with Pool(processes=snakemake.threads) as pool: pool.starmap(process_group, args) - - -