diff --git a/workflow/Snakefile b/workflow/Snakefile index 9a162845..760c90fa 100644 --- a/workflow/Snakefile +++ b/workflow/Snakefile @@ -673,6 +673,9 @@ rule plot_ariadne_report: elec_price_duration_curve=RESULTS + "ariadne/report/elec_price_duration_curve.png", elec_price_duration_hist=RESULTS + "ariadne/report/elec_price_duration_hist.png", + backup_capacity=RESULTS + "ariadne/report/backup_capacity.png", + backup_generation=RESULTS + "ariadne/report/backup_generation.png", + elec_prices_spatial_de=RESULTS + "ariadne/report/elec_prices_spatial_de.png", results=directory(RESULTS + "ariadne/report"), elec_transmission=directory(RESULTS + "ariadne/report/elec_transmission"), h2_transmission=directory(RESULTS + "ariadne/report/h2_transmission"), diff --git a/workflow/scripts/plot_ariadne_report.py b/workflow/scripts/plot_ariadne_report.py index c6d4a241..c05506e9 100644 --- a/workflow/scripts/plot_ariadne_report.py +++ b/workflow/scripts/plot_ariadne_report.py @@ -5,9 +5,10 @@ sys.path.insert(0, os.path.abspath(os.path.dirname(__file__))) from datetime import datetime -from itertools import compress +from itertools import compress, islice from multiprocessing import Pool +import cartopy import cartopy.crs as ccrs import geopandas as gpd import matplotlib.dates as mdates @@ -53,6 +54,42 @@ # "methane": "gas", } +backup_techs = { + "Gas": [ + "OCGT", + "CCGT", + "biogas", + "urban central gas CHP", + "urban central gas CHP CC", + ], + "Öl": ["oil", "urban central oil CHP"], + "Kohle": ["lignite", "coal", "urban central coal CHP", "urban central lignite CHP"], + "Wasserkraft": ["PHS", "hydro"], + "Batterie": ["battery discharger", "home battery discharger"], + "Wasserstoff": [ + "H2 OCGT", + "H2 retrofit OCGT", + "urban central H2 CHP", + "urban central H2 retrofit CHP", + ], + "Müllverbrennung": ["waste CHP", "waste CHP CC"], + "Biomasse": [ + "solid biomass", + "urban central solid biomass CHP", + "urban central solid biomass CHP CC", + ], +} + +vre_gens = [ + "onwind", + "offwind-ac", + "offwind-dc", + "solar", + "solar-hsat", + "solar rooftop", + "ror", +] + year_colors = [ "dimgrey", "darkorange", @@ -162,6 +199,150 @@ "DC", ] +carriers_in_german = { + "DC": "Gleichstrom", + "AC": "Wechselstrom", + "hydro": "Wasserkraft (Reservoir & Damm)", + "offwind-ac": "Offshore-Wind (AC)", + "offwind-dc": "Offshore-Wind (DC)", + "solar": "Solar", + "solar-hsat": "Solar (HSAT)", + "onwind": "Onshore-Wind", + "PHS": "Pumpspeicherkraftwerk", + "ror": "Laufwasserkraft", + "": "", + "lignite": "Braunkohle", + "coal": "Steinkohle", + "oil": "Öl", + "uranium": "Uran", + "none": "keine", + "co2": "CO2", + "co2 stored": "CO2 gespeichert", + "co2 sequestered": "CO2 sequestriert", + "gas": "Gas", + "H2": "Wasserstoffspeicher", + "battery": "Batteriespeicher", + "EV battery": "Elektrofahrzeug-Batterie", + "urban central heat": "Zentrale städtische Heizung", + "urban central water tanks": "Zentrale städtische Wassertanks", + "urban central solar thermal": "Zentrale städtische Solarthermie", + "biogas": "Biogas", + "solid biomass": "Biomasse", + "methanol": "Methanol", + "home battery": "Hausbatterie", + "rural heat": "Ländliche Wärme", + "rural solar thermal": "Ländliche Solarthermie", + "rural water tanks": "Ländliche Wassertanks", + "urban decentral heat": "Dezentrale städtische Heizung", + "urban decentral solar thermal": "Dezentrale städtische Solarthermie", + "urban decentral water tanks": "Dezentrale städtische Wassertanks", + "oil primary": "Primäröl", + "solar rooftop": "Solar-Dach", + "urban central heat vent": "Zentrale städtische Wärmeentlüftung", + "gas primary": "Primärgas", + "solid biomass for industry": "Biomasse (Industrie)", + "shipping oil": "Schiffsöl", + "agriculture machinery oil": "Landwirtschaftsmaschinenöl", + "naphtha for industry": "Naphtha für die Industrie", + "land transport oil": " Öl (Transport)", + "kerosene for aviation": "Kerosin für die Luftfahrt", + "non-sequestered HVC": "Nicht-sequestriertes HVC", + "shipping methanol": "Methanol für Schifffahrt", + "gas for industry": "Gas (Industrie)", + "low voltage": "Niederspannung", + "industry methanol": "Methanol (Industrie)", + "coal for industry": "Kohle (Industrie)", + "process emissions": "Prozessemissionen", + "industry electricity": "Industrieelektrizität", + "low-temperature heat for industry": "Niedertemperaturwärme (Industrie)", + "agriculture electricity": "Landwirtschaftliche Elektrizität", + "electricity": "Elektrizität", + "land transport EV": "Elektrofahrzeuge (Transport)", + "agriculture heat": "Landwirtschaftliche Wärme", + "urban central air heat pump": "Zentrale städtische Luftwärmepumpe", + "electricity distribution grid": "Stromverteilungsnetz", + "battery charger": "Batterie Laden", + "waste CHP": "Müll-KWK", + "urban central water tanks discharger": "Entladung zentraler städtischer Wassertanks", + "rural water tanks discharger": "Entladung ländlicher Wassertanks", + "urban decentral biomass boiler": "Dezentrale städtische Biomassekessel", + "BEV charger": "E-Fahrzeug Laden", + "rural ground heat pump": "Erdwärmepumpe", + "Fischer-Tropsch": "Fischer-Tropsch", + "urban decentral water tanks discharger": "Entladung dezentraler städtischer Wassertanks", + "urban central gas CHP": "Gas-KWK", + "Sabatier": "Sabatier-Prozess", + "gas compressing": "Gasverdichtung", + "home battery charger": "Hausbatterie Laden", + "battery discharger": "Batterie Entladung", + "H2 pipeline retrofitted": "Nachgerüstete Wasserstoffpipeline", + "rural resistive heater": "Ländlicher Widerstandsheizer", + "urban central water tanks charger": "Ladung zentraler städtischer Wassertanks", + "urban central solid biomass CHP CC": "Biomasse-KWK mit CO2-Abscheidung", + "rural air heat pump": "Ländliche Luftwärmepumpe", + "DAC": "Direkte CO2-Abscheidung", + "urban decentral air heat pump": "Dezentrale städtische Luftwärmepumpe", + "waste CHP CC": "Müll-KWK mit CO2-Abscheidung", + "biomass to liquid CC": "Biomasse zu Flüssigkeit mit CO2-Abscheidung", + "HVC to air": "HVC in die Luft", + "methanolisation": "Methanolisation", + "gas for industry CC": "Gas mit CO2-Abscheidung (Industrie)", + "H2 pipeline": "Wasserstoffpipeline", + "solid biomass for industry CC": "Biomasse mit CO2-Abscheidung (Industrie)", + "urban decentral gas boiler": "Dezentrale städtische Gaskessel", + "urban central gas CHP CC": "Gas-KWK mit CO2-Abscheidung", + "rural gas boiler": "Ländlicher Gaskessel", + "process emissions CC": "Prozessemissionen mit CO2-Abscheidung", + "urban decentral water tanks charger": "Ladung dezentraler städtischer Wassertanks", + "biogas to gas CC": "Biogas zu Gas mit CO2-Abscheidung", + "urban decentral resistive heater": "Dezentrale städtische Widerstandsheizer", + "biogas to gas": "Biogas zu Gas", + "OCGT": "Gas (OCGT)", + "urban central solid biomass CHP": "Biomasse-KWK", + "urban central gas boiler": "Zentraler städtischer Gaskessel", + "urban central resistive heater": "Zentraler städtischer Widerstandsheizer", + "oil refining": "Ölraffinierung", + "rural biomass boiler": "Ländlicher Biomassekessel", + "SMR": "Dampfreformierung", + "biomass to liquid": "Biomasse zu Flüssigkeit", + "rural water tanks charger": "Ladung ländlicher Wassertanks", + "home battery discharger": "Hausbatterie Entladung", + "H2 Store": "Wasserstoffspeicher", + "renewable oil": "Erneuerbares Öl", + "renewable gas": "Erneuerbares Gas", + "CCGT": "Gas (CCGT)", + "nuclear": "Kernenergie", + "gas CHP": "Gas-KWK", + "gas CHP CC": "Gas KWK mit CO2-Abscheidung", + "urban central coal CHP": "Steinkohle-KWK", + "Electricity trade": "Stromhandel", + "urban central gas CHP": "Gas-KWK", + "urban central biomass CHP": " Biomasse-KWK", + "biomass CHP": "Biomasse-KWK", + "air heat pump": "Luftwärmepumpe", + "Electricity load": "Elektrizitätslast", + "methanolisation": "Methanolisierung", + "resistive heater": "Widerstandsheizer", + "gas boiler": "Gaskessel", + "H2 Electrolysis": "Elektrolyse", + "H2 Fuel Cell": "Brennstoffzelle (Strom)", + "H2 for industry": "H2 für Industrie", + "H2 OCGT": "Wasserstoff (OCGT)", + "H2 CHP": "H2 KWK", + "land transport fuel cell": "Brennstoffzelle (Verkehr)", + "other": "Sonstige", + "SMR CC": "Dampfreformierung mit CCS", + "H2 pipeline (new)": "H2 Pipeline (Neubau)", + "H2 pipeline (repurposed)": "H2 Pipeline (Umstellung)", + "H2 pipeline (Kernnetz)": "H2 Pipeline (Kernnetz)", + "heat pump": "Wärmepumpe", + "urban central H2 CHP": "Wasserstoff-KWK", + "urban central H2 retrofit CHP": "Wasserstoff-KWK (Umrüstung)", + "urban central oil CHP": "Öl-KWK", + "urban central lignite CHP": "Braunkohle-KWK", + "H2 retrofit OCGT": "Wasserstoff (OCGT;Umrüstung)", +} + ####### functions ####### def get_condense_sum(df, groups, groups_name, return_original=False): @@ -209,6 +390,7 @@ def plot_nodal_balance( plot_loads=True, resample=None, nice_names=False, + german_carriers=False, threshold=1e-3, # in GWh condense_groups=None, condense_names=None, @@ -282,7 +464,10 @@ def plot_nodal_balance( network.buses[network.buses.carrier.isin(carriers)].index ].mean(axis=1)[period] ax2 = lmps.plot( - style="--", color="black", label="lmp (mean over buses)", secondary_y=True + style="--", + color="black", + label="Knotenpreise (gemittelt)", + secondary_y=True, ) ax2.grid(False) # set limits of secondary y-axis @@ -295,12 +480,12 @@ def plot_nodal_balance( 1.5 * lmps.max(), ] ) - ax2.legend(title="Legend for right y-axis", loc="upper right") - ax2.set_ylabel("lmp [€/MWh]") + ax2.legend(title="Legende für y-Ache (rechts)", loc="upper right") + ax2.set_ylabel("Knotenpreise [€/MWh]") # plot loads if plot_loads: - df_loads.plot(style=":", color="black", label="loads") + df_loads.plot(style=":", color="black", label="Elektrizitätslast") # explicitly filter out duplicate labels handles, labels = ax.get_legend_handles_labels() @@ -309,10 +494,14 @@ def plot_nodal_balance( ] handles, labels = zip(*filtered_handles_labels) - if nice_names: + if nice_names & (not german_carriers): nice_names_dict = network.carriers.nice_name.to_dict() labels = [nice_names_dict.get(l, l) for l in labels] + if german_carriers: + german_carriers + labels = [carriers_in_german.get(l, l) for l in labels] + # rescale the y-axis ax.set_ylim([1.05 * df_neg.sum(axis=1).min(), 1.05 * df_pos.sum(axis=1).max()]) ax.legend( @@ -321,13 +510,13 @@ def plot_nodal_balance( ncol=1, loc="upper center", bbox_to_anchor=(1.22 if plot_lmps else 1.13, 1.01), - title="Legend for left y-axis" if plot_lmps else "Legend", + title="Legende y-Achse (links)" if plot_lmps else "Legende", ) ax.set_ylabel(ylabel) ax.set_xlabel("") ax.set_title( - f"{title} ({model_run}; {datetime.strptime(start_date, date_format).strftime(reduced_date_format)} - {datetime.strptime(end_date, date_format).strftime(reduced_date_format)})", + f"{title} ({model_run})", fontsize=16, pad=15, ) @@ -620,6 +809,11 @@ def plot_price_duration_curve( languange="english", ): + # only plot 2030 onwards + years = years[2:] + networks = dict(islice(networks.items(), 2, None)) + year_colors = year_colors[2:] + fig, ax = plt.subplots(ncols=1, nrows=1, figsize=(8, 6)) for i, n in enumerate(networks.values()): @@ -715,6 +909,303 @@ def plot_price_duration_hist( return fig +def plot_backup_capacity( + networks, tech_colors, savepath, backup_techs, vre_gens, region="DE" +): + + kwargs = { + "groupby": networks[2020].statistics.groupers.get_name_bus_and_carrier, + "nice_names": False, + } + + df_all = pd.DataFrame() + + for year in np.arange(2020, 2050, 5): + + n = networks[year] + + electricity_cap = ( + n.statistics.optimal_capacity(bus_carrier=["low voltage", "AC"], **kwargs) + .filter(like=region) + .groupby(["carrier"]) + .sum() + .drop( + ["AC", "DC", "electricity distribution grid"], + errors="ignore", + ) + ) + + df = round(electricity_cap.sort_values(ascending=False) / 1e3, 2) + non_vre_gens = df[~df.index.isin(vre_gens)].index + df = df.loc[non_vre_gens] + df = df[df > 1e-3] + + df_all = pd.concat([df_all, df], axis=1) + + df_all.columns = np.arange(2020, 2050, 5) + + tech_colors["coal"] = "black" + + # Create figure + plt.figure(figsize=(20, 5)) + + # Track x-axis positions + x_positions = [] + x_labels = [] + x_offset = 0 + + df = df_all + + # Plot for each group + for group, techs_in_group in backup_techs.items(): + # Find matching techs in the dataframe + matching_techs = [tech for tech in techs_in_group if tech in df.index] + + # Prepare data for this group + group_data = df.loc[matching_techs] + + # Prepare bottom for stacking + bottom = np.zeros(len(group_data.columns)) + + # Plot each technology in the group + for j, tech in enumerate(matching_techs): + values = group_data.loc[tech].fillna(0) + plt.bar( + np.arange(len(group_data.columns)) + x_offset, + values, + 1, + bottom=bottom, + label=tech, + color=tech_colors[tech], + ) + bottom += values + + # Store x-axis positions for this group + x_positions.append(x_offset + len(group_data.columns) / 2) + x_labels.append(group) + + # Update x offset with extra spacing + x_offset += len(group_data.columns) + 1 # Add extra space between groups + + plt.ylim(0, 100) + + # Customize the plot + plt.title("Kapazität Backup-Kraftwerke (Strom)", fontsize=16) + plt.ylabel("MW", fontsize=12) + + # Create custom x-tick labels with group names below years + x_ticks = np.concatenate( + [ + np.arange(len(df.columns)) + i + for i in range(0, x_offset, len(df.columns) + 1) + ] + ) + x_tick_labels = np.tile(df.columns, len(backup_techs)) + + plt.xticks(x_ticks, x_tick_labels, rotation=45) + + # Add group labels below x-axis ticks + for pos, label in zip(x_positions, x_labels): + plt.text( + pos, + plt.gca().get_ylim()[0] - plt.gca().get_ylim()[1] * 0.15, + label, + horizontalalignment="center", + verticalalignment="top", + fontweight="bold", + ) + + plt.grid(axis="y") + + # Replace legend labels with German names from carriers_in_german + handles, labels = plt.gca().get_legend_handles_labels() + new_labels = [ + carriers_in_german.get(label, label) for label in labels + ] # Replace labels if in dict + plt.legend(handles, new_labels, loc="upper center", ncol=7) + + plt.tight_layout() + plt.savefig(savepath, bbox_inches="tight") + + +def plot_backup_generation( + networks, tech_colors, savepath, backup_techs, vre_gens, region="DE" +): + + tech_colors["coal"] = "black" + + kwargs = { + "groupby": networks[2020].statistics.groupers.get_name_bus_and_carrier, + "nice_names": False, + } + + df_all = pd.DataFrame() + + for year in np.arange(2020, 2050, 5): + n = networks[year] + + electricity_supply_de = ( + n.statistics.supply(bus_carrier=["low voltage", "AC"], **kwargs) + .filter(like=region) + .groupby(["carrier"]) + .sum() + .drop( + ["AC", "DC", "electricity distribution grid"], + errors="ignore", + ) + ) + + df = round(electricity_supply_de.sort_values(ascending=False) / 1e6, 2) + non_vre_gens = df[~df.index.isin(vre_gens)].index + df = df.loc[non_vre_gens] + df = df[df > 0.01] + df_all = pd.concat([df_all, df], axis=1) + + df_all.columns = np.arange(2020, 2050, 5) + + # Create figure + plt.figure(figsize=(20, 5)) + + # Track x-axis positions + x_positions = [] + x_labels = [] + x_offset = 0 + + df = df_all + + # Plot for each group + for group, techs_in_group in backup_techs.items(): + # Find matching techs in the dataframe + matching_techs = [tech for tech in techs_in_group if tech in df.index] + + # Prepare data for this group + group_data = df.loc[matching_techs] + + # Prepare bottom for stacking + bottom = np.zeros(len(group_data.columns)) + + # Plot each technology in the group + for j, tech in enumerate(matching_techs): + values = group_data.loc[tech].fillna(0) + plt.bar( + np.arange(len(group_data.columns)) + x_offset, + values, + 1, + bottom=bottom, + label=tech, + color=tech_colors[tech], + ) + bottom += values + + # Store x-axis positions for this group + x_positions.append(x_offset + len(group_data.columns) / 2) + x_labels.append(group) + + # Update x offset with extra spacing + x_offset += len(group_data.columns) + 1 # Add extra space between groups + + plt.ylim(0, 200) + + # Customize the plot + plt.title("Versorgung Backup-Kraftwerke (Strom)", fontsize=16) + plt.ylabel("TWh", fontsize=12) + + # Create custom x-tick labels with group names below years + x_ticks = np.concatenate( + [ + np.arange(len(df.columns)) + i + for i in range(0, x_offset, len(df.columns) + 1) + ] + ) + x_tick_labels = np.tile(df.columns, len(backup_techs)) + + plt.xticks(x_ticks, x_tick_labels, rotation=45) + + # Add group labels below x-axis ticks + for pos, label in zip(x_positions, x_labels): + plt.text( + pos, + plt.gca().get_ylim()[0] - plt.gca().get_ylim()[1] * 0.15, + label, + horizontalalignment="center", + verticalalignment="top", + fontweight="bold", + ) + + plt.grid(axis="y") + + # Replace legend labels with German names from carriers_in_german + handles, labels = plt.gca().get_legend_handles_labels() + new_labels = [ + carriers_in_german.get(label, label) for label in labels + ] # Replace labels if in dict + plt.legend(handles, new_labels, loc="upper center", ncol=7) + + plt.tight_layout() + plt.savefig(savepath, bbox_inches="tight") + + +def plot_elec_prices_spatial( + network, tech_colors, savepath, onshore_regions, year="2045", region="DE" +): + + # onshore_regions = gpd.read_file("/home/julian-geis/repos/pypsa-ariadne-1/resources/20241203-force-onwind-south-49cl-disc/KN2045_Bal_v4/regions_onshore_base_s_49.geojson") + # onshore_regions = onshore_regions.set_index('name') + + n = network + buses = n.buses[n.buses.carrier == "AC"].index + + df = onshore_regions + df["elec_price"] = n.buses_t.marginal_price[buses].mean() + + # Create figure + fig, ax = plt.subplots( + 1, 1, subplot_kw={"projection": ccrs.PlateCarree()}, figsize=(9, 6) + ) + crs = ccrs.PlateCarree() + + mvs = df["elec_price"][df.index.str.contains("DE")] + vmin = np.nanmin(mvs) + vmax = np.nanmax(mvs) + + ax.add_feature(cartopy.feature.BORDERS, edgecolor="black", linewidth=0.5) + ax.coastlines(edgecolor="black", linewidth=0.5) + ax.set_facecolor("white") + ax.add_feature(cartopy.feature.OCEAN, color="azure") + + df[df.index.str.contains("DE")].to_crs(crs.proj4_init).plot( + column=f"elec_price", + ax=ax, + cmap=plt.get_cmap("magma_r"), + linewidth=0.05, + edgecolor="grey", + legend=True, + vmin=vmin, + vmax=vmax, + legend_kwds={ + "label": "Strompreise ($€/MWh$)", + "orientation": "vertical", + "shrink": 0.9, + }, + ) + + # max_size = df[f"{carriers[i]}_gen"].max() + # df.to_crs(crs.proj4_init).centroid.plot(ax=ax, sizes=df[f"{carriers[i]}_gen"] / max_size *300, color="black", edgecolor="white") + # pypsa.plot.add_legend_circles(ax=ax, sizes=[0.6], labels=["Generation magnitude"], patch_kw={'color': 'black', 'edgecolor': 'white'}, legend_kw={'loc': 'upper left'}) + + # Set geographic extent for Germany + ax.set_extent([5, 16, 47, 56], ccrs.PlateCarree()) # Germany bounds + # ax.set_title(f"{carriers[i]}", fontsize=16, **font1) + + # fig.suptitle(f"Spatial Differences in the electricity generation of the VRE technologies ({model})", fontsize=16, **font1) + fig.tight_layout() + + # plt.close() + plt.show() + + fig.savefig(savepath, bbox_inches="tight") + + def assign_location(n): for c in n.iterate_components(n.one_port_components | n.branch_components): ifind = pd.Series(c.df.index.str.find(" ", start=4), c.df.index) @@ -895,7 +1386,7 @@ def plot_h2_map(n, regions, savepath, only_de=False): vmax=6, vmin=0, legend_kwds={ - "label": "Hydrogen Storage [TWh]", + "label": "Wasserstoffspeicher [TWh]", "shrink": 0.7, "extend": "max", }, @@ -948,12 +1439,15 @@ def plot_h2_map(n, regions, savepath, only_de=False): color_retrofit, color_kern, ] + labels = carriers + [ "H2 pipeline (new)", "H2 pipeline (repurposed)", "H2 pipeline (Kernnetz)", ] + labels = [carriers_in_german.get(c, c) for c in labels] + legend_kw = dict( loc="upper left", bbox_to_anchor=(0, 1.13), @@ -1207,7 +1701,7 @@ def rename_carriers(carrier): vmax=6, vmin=0, legend_kwds={ - "label": "Hydrogen Storage [TWh]", + "label": "Wasserstoffspeicher [TWh]", "shrink": 0.7, "extend": "max", }, @@ -1281,6 +1775,8 @@ def rename_carriers(carrier): "H2 pipeline (Kernnetz)", ] + labels = [carriers_in_german.get(c, c) for c in labels] + legend_kw = dict( loc="upper left", bbox_to_anchor=(0, 1.13), @@ -1409,7 +1905,7 @@ def plot_elec_map_de( linewidths=0, legend=True, legend_kwds={ - "label": "Battery Storage [GWh]", + "label": "Batteriespeicher [GWh]", "shrink": 0.7, "extend": "max", }, @@ -1814,10 +2310,17 @@ def plot_cap_map_de( for n, my, c in zip(_networks, modelyears, costs) ] del _networks - ### + + # # for running with explicit networks not within repo structur (comment out load data and load regions) + # diry = "postnetworks-folder" + # file_list = os.listdir(diry) + # file_list.sort() + # networks = [pypsa.Network(diry+"/"+fn) for fn in file_list] + # modelyears = [fn[-7:-3] for fn in snakemake.input.networks] + # regions = gpd.read_file("path-to-file/regions_onshore_base_s_49.geojson").set_index("name") # ensure output directory exist - for dir in snakemake.output[2:]: + for dir in snakemake.output[5:]: if not os.path.exists(dir): os.makedirs(dir) @@ -1887,11 +2390,12 @@ def plot_cap_map_de( resample="D", plot_lmps=False, plot_loads=False, - nice_names=True, + german_carriers=True, threshold=1e2, # in GWh as sum over period condense_groups=c_g, condense_names=c_n, title="Strombilanz", + ylabel="Stromerzeugung/ -verbrauch [GW]", ) plot_nodal_balance( @@ -1902,11 +2406,12 @@ def plot_cap_map_de( end_date="2019-01-31 00:00:00", savepath=f"{snakemake.output.elec_balances}/elec-Jan-DE-{year}.png", model_run=snakemake.wildcards.run, - nice_names=True, + german_carriers=True, threshold=1e2, condense_groups=[electricity_load, electricity_imports], condense_names=["Electricity load", "Electricity trade"], title="Strombilanz", + ylabel="Stromerzeugung/ -verbrauch [GW]", ) plot_nodal_balance( @@ -1917,11 +2422,12 @@ def plot_cap_map_de( end_date="2019-05-31 00:00:00", savepath=f"{snakemake.output.elec_balances}/elec-May-DE-{year}.png", model_run=snakemake.wildcards.run, - nice_names=True, + german_carriers=True, threshold=1e2, condense_groups=[electricity_load, electricity_imports], condense_names=["Electricity load", "Electricity trade"], title="Strombilanz", + ylabel="Stromerzeugung/ -verbrauch [GW]", ) # heat supply and demand @@ -1943,7 +2449,7 @@ def plot_cap_map_de( condense_groups=c_g, condense_names=c_n, carriers=[carriers], - ylabel="Heat [GW]", + ylabel="Wärme [GW]", title=f"{carriers} balance", ) @@ -2012,12 +2518,42 @@ def plot_cap_map_de( years=planning_horizons, ) + plot_backup_capacity( + networks=networks_dict, + tech_colors=tech_colors, + savepath=snakemake.output.backup_capacity, + backup_techs=backup_techs, + vre_gens=vre_gens, + region="DE", + ) + + plot_backup_generation( + networks=networks_dict, + tech_colors=tech_colors, + savepath=snakemake.output.backup_generation, + backup_techs=backup_techs, + vre_gens=vre_gens, + region="DE", + ) + + # load regions + regions = gpd.read_file(snakemake.input.regions_onshore_clustered).set_index("name") + + year = 2045 + plot_elec_prices_spatial( + network=networks[planning_horizons.index(year)].copy(), + tech_colors=tech_colors, + onshore_regions=regions, + savepath=snakemake.output.elec_prices_spatial_de, + region="DE", + year=year, + ) + ## hydrogen transmission logger.info("Plotting hydrogen transmission") map_opts = snakemake.params.plotting["map"] 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()