Added generation scatterplots, added stack plots

This commit is contained in:
Lukas Franken 2023-05-01 22:41:54 +02:00 committed by GitHub
parent 70b8ec7e44
commit 325ec50e11
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -12,12 +12,10 @@
"import os\n", "import os\n",
"from pathlib import Path\n", "from pathlib import Path\n",
"import matplotlib.pyplot as plt\n", "import matplotlib.pyplot as plt\n",
"\n",
"plt.style.use(\"ggplot\")\n", "plt.style.use(\"ggplot\")\n",
"import pycountry\n", "import pycountry\n",
"import json\n", "import json\n",
"import warnings\n", "import warnings\n",
"\n",
"warnings.filterwarnings(\"ignore\")" "warnings.filterwarnings(\"ignore\")"
] ]
}, },
@ -28,15 +26,15 @@
"outputs": [], "outputs": [],
"source": [ "source": [
"available_models = {\n", "available_models = {\n",
" \"model_1\": \"elec_s_37_ec_lv1.0_.nc\",\n", " \"model_1\": \"elec_s_37_ec_lv1.0_.nc\", \n",
" \"model_2\": \"elec_s_37_ec_lv1.0_3H_withUC.nc\",\n", " \"model_2\": \"elec_s_37_ec_lv1.0_3H_withUC.nc\",\n",
" \"model_3\": \"elec_s_37_ec_lv1.0_Co2L-noUC-noCo2price.nc\",\n", " \"model_3\": \"elec_s_37_ec_lv1.0_Co2L-noUC-noCo2price.nc\",\n",
" \"model_4\": \"elec_s_37_ec_lv1.0_Ep.nc\",\n", " \"model_4\": \"elec_s_37_ec_lv1.0_Ep.nc\", \n",
" \"model_5\": \"elec_s_37_ec_lv1.0_Ep_new.nc\",\n", " \"model_5\": \"elec_s_37_ec_lv1.0_Ep_new.nc\", \n",
"}\n", "}\n",
"\n", "\n",
"data_path = Path.cwd() / \"..\" / \"..\"\n", "data_path = Path.cwd() / \"..\" / \"..\"\n",
"model_path = data_path / available_models[\"model_5\"]\n", "model_path = data_path / available_models[\"model_5\"]\n",
"\n", "\n",
"with open(data_path / \"generation_data\" / \"generation_mapper_pypsa.json\", \"r\") as f:\n", "with open(data_path / \"generation_data\" / \"generation_mapper_pypsa.json\", \"r\") as f:\n",
" pypsa_generation_mapper = json.load(f)" " pypsa_generation_mapper = json.load(f)"
@ -58,10 +56,11 @@
"outputs": [], "outputs": [],
"source": [ "source": [
"def intersection(alist, blist):\n", "def intersection(alist, blist):\n",
" total_list = list()\n",
" for val in alist:\n", " for val in alist:\n",
" if val not in blist:\n", " if val in blist:\n",
" alist.remove(val)\n", " total_list.append(val)\n",
" return alist" " return total_list "
] ]
}, },
{ {
@ -83,11 +82,13 @@
"gen = set([col[6:] for col in n.generators_t.p.columns])\n", "gen = set([col[6:] for col in n.generators_t.p.columns])\n",
"\n", "\n",
"for i, country in enumerate(countries):\n", "for i, country in enumerate(countries):\n",
"\n",
" df = pd.DataFrame(index=n.generators_t.p.index)\n", " df = pd.DataFrame(index=n.generators_t.p.index)\n",
" # country_generation = [col for col in n.generators_t.p.columns if col.startswith(country)]\n", " # country_generation = [col for col in n.generators_t.p.columns if col.startswith(country)]\n",
" country_generation = n.generators.loc[n.generators.bus.str.contains(country)]\n", " country_generation = n.generators.loc[n.generators.bus.str.contains(country)]\n",
"\n", "\n",
" for key, gens in pypsa_generation_mapper.items():\n", " for key, gens in pypsa_generation_mapper.items():\n",
"\n",
" # curr_gen = country_generation.loc[\n", " # curr_gen = country_generation.loc[\n",
" # (country_generation.carrier.str.contains(tech) for tech in gens).astype(bool)].index\n", " # (country_generation.carrier.str.contains(tech) for tech in gens).astype(bool)].index\n",
" curr_gen = country_generation.loc[\n", " curr_gen = country_generation.loc[\n",
@ -95,11 +96,12 @@
" ].index\n", " ].index\n",
"\n", "\n",
" if len(curr_gen):\n", " if len(curr_gen):\n",
" df[key] = n.generators_t.p[curr_gen].mean(axis=1)\n", " df[key] = n.generators_t.p[curr_gen].mean(axis=1) \n",
" else:\n", " else:\n",
" df[key] = np.zeros(len(df))\n", " df[key] = np.zeros(len(df))\n",
"\n", "\n",
" df.to_csv(data_path / \"pypsa_data\" / (country + \".csv\"))" " df.to_csv(data_path / \"pypsa_data\" / (country+\".csv\"))\n",
" "
] ]
}, },
{ {
@ -109,235 +111,322 @@
"outputs": [], "outputs": [],
"source": [ "source": [
"import seaborn as sns\n", "import seaborn as sns\n",
"from sklearn.metrics import mean_absolute_error\n",
"\n", "\n",
"\n", "\n",
"for num, country in enumerate(os.listdir(data_path / \"pypsa_data\")):\n", "for num, country in enumerate(os.listdir(data_path / \"pypsa_data\")):\n",
" # country = \"DE.csv\"\n", "\n",
" # country = \"GR.csv\"\n",
" cc = country[:2]\n", " cc = country[:2]\n",
"\n", "\n",
" pypsa_df = pd.read_csv(\n", " country_buses = np.unique(n.generators.loc[n.generators.bus.str.contains(cc)].bus.values)\n",
" data_path / \"pypsa_data\" / country, parse_dates=True, index_col=0\n", " print(f\"Buses for country {country[:-4]}: \", country_buses)\n",
" )\n",
" try:\n",
" entsoe_df = pd.read_csv(\n",
" data_path / \"harmonised_generation_data\" / (\"prepared_\" + country),\n",
" parse_dates=True,\n",
" index_col=0,\n",
" )\n",
"\n", "\n",
" entsoe_df.columns = [col[:-6] for col in entsoe_df.columns]\n", " if not len(country_buses) == 1:\n",
" except FileNotFoundError:\n", " print(\"Current implementation is for one bus per country\")\n",
" print(f\"Skipping!\")\n",
" continue\n", " continue\n",
"\n", "\n",
" fig, axs = plt.subplots(3, 3, figsize=(20, 15))\n", " bus = country_buses[0]\n",
"\n", "\n",
" axs[0, 0].set_title(pycountry.countries.get(alpha_2=country[:2]).name)\n", " \"\"\" \n",
" pypsa_df = pd.read_csv(data_path / \"pypsa_data\" / country, parse_dates=True, index_col=0)\n",
" \"\"\" \n",
" try:\n",
" entsoe_df = pd.read_csv(data_path / \"harmonised_generation_data\" / (\"prepared_\"+country),\n",
" parse_dates=True,\n",
" index_col=0)\n",
"\n", "\n",
" start = pd.Timestamp(\"2019-01-01\") # for small time frame\n", " entsoe_df.columns = [col[:-6] for col in entsoe_df.columns]\n",
" entsoe_df = entsoe_df.iloc[1:]\n",
" entsoe_df = entsoe_df.multiply(1e-3)\n",
" except FileNotFoundError:\n",
" continue \n",
" \n",
" fig, axs = plt.subplots(4, 3, figsize=(20, 20))\n",
"\n",
" axs[0,0].set_title(pycountry.countries.get(alpha_2=country[:2]).name)\n",
"\n",
" start = pd.Timestamp(\"2019-01-01\") # for small time frame\n",
" end = pd.Timestamp(\"2019-01-14\")\n", " end = pd.Timestamp(\"2019-01-14\")\n",
" coarse_freq = \"d\"\n", " coarse_freq = \"3d\"\n",
"\n", "\n",
" num_techs_shown = 6\n", " num_techs_shown = 6\n",
"\n", "\n",
" links = n.links.loc[\n", " energy_inflow = pd.DataFrame(index=n.loads_t.p_set.index)\n",
" (n.links.bus0.str.contains(cc) + n.links.bus1.str.contains(cc)).astype(bool)\n", " energy_outflow = pd.DataFrame(index=n.loads_t.p_set.index)\n",
" ]\n",
" links = links.loc[links.carrier == \"DC\"].sum(axis=1)\n",
"\n", "\n",
" from_here = n.links.loc[links.index].bus0.str.contains(cc)\n", " # add generation\n",
" to_here = n.links.loc[links.index].bus1.str.contains(cc)\n", " country_gen = n.generators.loc[n.generators.bus == bus]\n",
"\n", "\n",
" pypsa_df[\"Import Export\"] = pd.concat(\n", " for tech, pypsa_carrier in pypsa_generation_mapper.items():\n",
" (n.links_t.p0[from_here.index], n.links_t.p0[to_here.index]), axis=1\n", " gens = country_gen.loc[country_gen.carrier.apply(lambda c: c in pypsa_carrier)].index\n",
" ).sum(axis=1)\n", " energy_inflow[tech] = n.generators_t.p[gens].sum(axis=1)\n",
"\n", "\n",
" # show_techs = pypsa_df.sum().sort_values(ascending=False).iloc[:num_techs_shown].index.tolist()\n", " # add inflows from lines\n",
" show_techs = (\n", " lines0 = n.lines.loc[n.lines.bus0 == bus].index\n",
" entsoe_df.sum()\n", " lines1 = n.lines.loc[n.lines.bus1 == bus].index\n",
" .sort_values(ascending=False)\n",
" .iloc[:num_techs_shown]\n",
" .index.tolist()\n",
" )\n",
"\n", "\n",
" entsoe_df[intersection(show_techs, entsoe_df.columns.tolist())].loc[start:end].plot(\n", " lines_flow = np.zeros(energy_inflow.shape[0])\n",
" ax=axs[0, 0]\n", " if not lines0.empty:\n",
" )\n", " lines_flow = - n.lines_t.p0[lines0].sum(axis=1)\n",
" pypsa_df[show_techs].loc[start:end].plot(ax=axs[0, 1], legend=False)\n", " \n",
" if not lines1.empty:\n",
" lines_flow -= n.lines_t.p1[lines1].sum(axis=1)\n",
" \n",
" energy_inflow[\"Inflow Lines\"] = np.maximum(np.zeros_like(lines_flow), lines_flow)\n",
" energy_outflow[\"Outflow Lines\"] = np.minimum(np.zeros_like(lines_flow), lines_flow)\n",
"\n", "\n",
" pypsa_load = n.loads_t.p_set\n", " # add inflows from links\n",
" pypsa_load = pypsa_load[\n", " links0 = n.links.loc[n.links.bus0 == bus].index\n",
" [col for col in pypsa_load.columns if col.startswith(country[:2])]\n", " links1 = n.links.loc[n.links.bus1 == bus].index\n",
" ].mean(axis=1)\n",
"\n", "\n",
" pypsa_load.loc[start:end].plot(ax=axs[0, 2])\n", " links_flow = np.zeros(energy_inflow.shape[0])\n",
" if not links0.empty:\n",
" links_flow = - n.links_t.p0[links0].multiply(n.links.loc[links0, \"efficiency\"]).sum(axis=1)\n",
"\n", "\n",
" axs[0, 0].set_ylabel(\"ENTSOE Generation\")\n", " if not links1.empty:\n",
" axs[0, 1].set_ylabel(\"PyPSA Generation\")\n", " links_flow -= n.links_t.p1[links1].multiply(n.links.loc[links1, \"efficiency\"]).sum(axis=1)\n",
" axs[0, 2].set_ylabel(\"PyPSA Load\")\n",
"\n", "\n",
" upper_lim = pd.concat((pypsa_df, entsoe_df), axis=0).max().max()\n", " energy_inflow[\"Inflow Links\"] = np.maximum(np.zeros_like(links_flow), links_flow)\n",
" for ax in axs[0, :2]:\n", " energy_outflow[\"Outflow Links\"] = np.minimum(np.zeros_like(links_flow), links_flow)\n",
" ax.set_ylim(0, upper_lim)\n",
"\n", "\n",
" for ax in axs[0, :2]:\n", " storage = n.storage_units.loc[n.storage_units.bus == bus].index\n",
" ax.legend()\n", " if not storage.empty:\n",
" storage_p = n.storage_units_t.p[storage].sum(axis=1).values\n",
" # energy_inflow[\"Storage Discharge\"] = np.maximum(np.zeros_like(links_flow), storage_p)\n",
" energy_inflow[\"Hydro\"] = energy_inflow[\"Hydro\"].values + np.maximum(np.zeros_like(links_flow), storage_p)\n",
" energy_outflow[\"Storage Charge\"] = np.minimum(np.zeros_like(links_flow), storage_p)\n",
"\n", "\n",
" # entsoe_df[[col+\" (MWh)\" for col in pypsa_df.columns]].loc[start:end].plot(ax=axs[0])\n", " energy_inflow = energy_inflow.iloc[:-1].multiply(1e-3)\n",
" entsoe_df[intersection(show_techs, entsoe_df.columns.tolist())].resample(\n", " energy_outflow = energy_outflow.iloc[:-1].multiply(1e-3)\n",
" coarse_freq\n", " load = n.loads_t.p_set[bus].iloc[:-1].multiply(1e-3)\n",
" ).mean().plot(ax=axs[1, 0])\n",
" pypsa_df[show_techs].resample(coarse_freq).mean().plot(ax=axs[1, 1], legend=False)\n",
"\n", "\n",
" pypsa_load = n.loads_t.p_set\n", " show_techs = energy_inflow.sum().sort_values(ascending=False).iloc[:num_techs_shown].index.tolist()\n",
" pypsa_load = pypsa_load[\n", " others = energy_inflow.sum().sort_values(ascending=False).iloc[num_techs_shown:].index.tolist()\n",
" [col for col in pypsa_load.columns if col.startswith(country[:2])]\n", " # show_techs = entsoe_df.sum().sort_values(ascending=False).iloc[:num_techs_shown].index.tolist()\n",
" ].mean(axis=1)\n",
" pypsa_load.resample(coarse_freq).sum().plot(ax=axs[1, 2])\n",
"\n", "\n",
" # pypsa_df[show_techs].resample(coarse_freq).mean().sum(axis=1).plot(ax=axs[1,2], legend=False)\n", " show_techs = intersection(show_techs, entsoe_df.columns.tolist())\n",
" entsoe_df[\"Others\"] = entsoe_df.drop(columns=show_techs).sum(axis=1)\n",
"\n", "\n",
" axs[1, 0].set_ylabel(\"ENTSOE Generation\")\n", " # entsoe_df[show_techs + [\"Others\"]].loc[start:end].plot.area(ax=axs[0,0])\n",
" axs[1, 1].set_ylabel(\"PyPSA Generation\")\n", " index = load.loc[start:end].index\n",
" axs[1, 2].set_ylabel(\"PyPSA Load\")\n",
"\n", "\n",
" upper_lim = (\n", " entsoe_df.index = load.index\n",
" pd.concat(\n",
" (\n",
" pypsa_df.resample(coarse_freq).mean(),\n",
" entsoe_df.resample(coarse_freq).mean(),\n",
" ),\n",
" axis=0,\n",
" )\n",
" .max()\n",
" .max()\n",
" )\n",
" for ax in axs[1, :2]:\n",
" ax.set_ylim(0, upper_lim)\n",
"\n", "\n",
" for ax in axs[1, :2]:\n", "\n",
" ax.legend()\n", " energy_inflow[\"Others\"] = energy_inflow.drop(columns=show_techs).sum(axis=1)\n",
" \n",
" # plot timeframe\n",
" axs[0,0].plot(index, load.loc[index].values, linestyle=\"--\", color=\"k\", linewidth=2, label=\"PyPSA Load\")\n",
" axs[0,1].plot(index, load.loc[index].values, linestyle=\"--\", color=\"k\", linewidth=2)\n",
"\n",
" axs[0,1].stackplot(index, *[energy_inflow[col].loc[index].values for col in show_techs + [\"Others\"]])\n",
" axs[0,1].stackplot(index, *[energy_outflow[col].loc[index].values for col in energy_outflow.columns],\n",
" colors=[\"seagreen\", \"royalblue\", \"gold\"],\n",
" labels=energy_outflow.columns\n",
" )\n",
"\n",
" axs[0,0].stackplot(index, *[entsoe_df[col].loc[index].values for col in show_techs + [\"Others\"]], labels=show_techs+[\"Others\"])\n",
" \n",
" axs[0,1].plot(index,\n",
" energy_inflow.loc[index][show_techs + [\"Others\"]].sum(axis=1).values + energy_outflow.loc[index].sum(axis=1).values,\n",
" color=\"brown\", linestyle=\":\", linewidth=2, label=\"Accum Gen\")\n",
"\n",
" axs[0,0].legend()\n",
" axs[0,1].legend()\n",
"\n",
" \n",
" # plot whole year\n",
"\n",
" index = load.resample(coarse_freq).mean().index\n",
"\n",
" axs[1,0].plot(index, load.resample(coarse_freq).mean().values, linestyle=\"--\", color=\"k\", linewidth=2, label=\"PyPSA Load\")\n",
" axs[1,1].plot(index, load.resample(coarse_freq).mean().values, linestyle=\"--\", color=\"k\", linewidth=2)\n",
"\n",
" axs[1,1].stackplot(index, *[energy_inflow[col].resample(coarse_freq).mean().values for col in show_techs + [\"Others\"]])\n",
" axs[1,1].stackplot(index, *[energy_outflow[col].resample(coarse_freq).mean().values for col in energy_outflow.columns],\n",
" colors=[\"seagreen\", \"royalblue\", \"gold\"],\n",
" labels=energy_outflow.columns\n",
" )\n",
"\n",
" axs[1,0].stackplot(index, *[entsoe_df[col].resample(coarse_freq).mean().values for col in show_techs + [\"Others\"]], labels=show_techs+[\"Others\"])\n",
"\n",
" axs[1,1].plot(index,\n",
" energy_inflow.resample(coarse_freq).mean()[show_techs + [\"Others\"]].sum(axis=1).values + \n",
" energy_outflow.resample(coarse_freq).mean().sum(axis=1).values,\n",
" color=\"brown\", linestyle=\":\", linewidth=2, label=\"Accum Gen\")\n",
"\n",
"\n",
" axs[1,0].legend()\n",
" axs[1,1].legend()\n",
"\n",
"\n",
" y_min = pd.concat([\n",
" energy_outflow.sum(axis=1)]).min()\n",
" y_max = pd.concat([\n",
" energy_inflow.sum(axis=1), entsoe_df.sum(axis=1)], ignore_index=True).max()\n",
"\n",
" for ax in axs[:2,:2].flatten():\n",
" ax.set_ylim(y_min, y_max)\n",
" ax.set_ylim(y_min, y_max)\n",
" \n",
" axs[0,0].set_ylabel(\"ENTSOE Gen and PyPSA Load [GW]\")\n",
" axs[0,1].set_ylabel(\"PyPSA Gen and Load [GW]\")\n",
" axs[1,0].set_ylabel(\"ENTSOE Gen and PyPSA Load [GW]\")\n",
" axs[1,1].set_ylabel(\"PyPSA Gen and Load [GW]\")\n",
" axs[2,0].set_ylabel(\"ENTSOE Gen and PyPSA Load [GW]\")\n",
" axs[2,1].set_ylabel(\"PyPSA Gen and Load [GW]\")\n",
"\n",
" # -------------------------- electricity prices comparison ----------------------------------\n",
" prices_col = [col for col in n.buses_t.marginal_price.columns if col.startswith(country[:2])]\n",
" pypsa_prices = n.buses_t.marginal_price[prices_col].mean(axis=1)\n",
"\n",
" full_index = pypsa_prices.index\n",
" \n",
" coarse_pypsa_prices = pypsa_prices.resample(coarse_freq).mean() \n",
" pypsa_prices = pypsa_prices.loc[start:end]\n",
"\n",
" axs[0,2].plot(pypsa_prices.index, pypsa_prices.values, label=\"PyPSA prices\", color=\"royalblue\")\n",
" axs[1,2].plot(coarse_pypsa_prices.index, coarse_pypsa_prices.values, label=\"PyPSA prices\", color=\"royalblue\")\n",
"\n", "\n",
" try:\n", " try:\n",
" entsoe_prices = pd.read_csv(\n", " entsoe_prices = pd.read_csv(data_path / \"price_data\" / country,\n",
" data_path / \"price_data\" / country,\n",
" index_col=0,\n", " index_col=0,\n",
" parse_dates=True,\n", " parse_dates=True,\n",
" )\n", " ).iloc[:-1]\n",
"\n",
" def make_tz_time(time):\n", " def make_tz_time(time):\n",
" return pd.Timestamp(time).tz_convert(\"utc\")\n", " return pd.Timestamp(time).tz_convert(\"utc\")\n",
"\n", "\n",
" entsoe_prices.index = pd.Series(entsoe_prices.index).apply(\n", " # entsoe_prices.index = pd.Series(entsoe_prices.index).apply(lambda time: make_tz_time(time))\n",
" lambda time: make_tz_time(time)\n", " entsoe_prices.index = full_index\n",
" )\n", " mean_abs_error = mean_absolute_error(entsoe_prices.values,\n",
" entsoe_prices.resample(\"3d\").mean().plot(ax=axs[2, 0])\n", " n.buses_t.marginal_price[prices_col].mean(axis=1).values)\n",
"\n",
" coarse_prices = entsoe_prices.resample(coarse_freq).mean()\n",
" entsoe_prices = entsoe_prices.loc[start:end]\n",
"\n",
" axs[0,2].plot(entsoe_prices.index, entsoe_prices.values, label=\"ENTSOE prices\", color=\"darkred\")\n",
" axs[1,2].plot(coarse_prices.index, coarse_prices.values, label=\"ENTSOE prices\", color=\"darkred\")\n",
"\n", "\n",
" except FileNotFoundError:\n", " except FileNotFoundError:\n",
" mean_abs_error = None\n",
" pass\n", " pass\n",
"\n", "\n",
" prices_col = [\n", " upper_lim = pd.concat((entsoe_prices, pypsa_prices), axis=0).max().max() \n",
" col for col in n.buses_t.marginal_price.columns if col.startswith(country[:2])\n", " for ax in axs[:2,2]:\n",
" ]\n",
" pypsa_prices = n.buses_t.marginal_price[prices_col].mean(axis=1)\n",
" pypsa_prices.resample(\"3d\").mean().plot(ax=axs[2, 1])\n",
"\n",
" upper_lim = pd.concat((entsoe_prices, pypsa_prices), axis=0).max().max()\n",
" for ax in axs[2, :2]:\n",
" ax.set_ylim(0, upper_lim)\n", " ax.set_ylim(0, upper_lim)\n",
" ax.set_ylabel(\"Electricty Prices [Euro/MWh]\")\n",
" ax.legend()\n",
" \n",
" if not mean_abs_error is None:\n",
" axs[1,-1].set_title(f\"Mean Abs Error: {np.around(mean_abs_error, decimals=2)}\") \n",
" \n",
" # remaining_cols = energy_inflow.drop(columns=show_techs+[\"Others\"]).columns.tolist()\n",
" # axs[1,0].set_title(f\"Others: {remaining_cols}\")\n",
"\n", "\n",
" axs[2, 0].set_ylabel(\"ENTSOE Day Ahead Prices\")\n", " # ------------------------------- duration curves ------------------------------\n",
" axs[2, 1].set_ylabel(\"PyPSA Shadow Prices\")\n",
"\n", "\n",
" pypsa_totals = pypsa_df.sum()\n", " entsoe_ddf = entsoe_df[show_techs + [\"Others\"]].reset_index(drop=True)\n",
"\n",
" entsoe_ddf = pd.concat([\n",
" entsoe_ddf[col].sort_values(ascending=False).reset_index(drop=True) for col in entsoe_ddf.columns\n",
" ], axis=1)\n",
"\n",
" axs[2,0].stackplot(range(len(entsoe_ddf)), *[entsoe_ddf[col].values for col in entsoe_ddf.columns],\n",
" labels=entsoe_ddf.columns)\n",
"\n",
" pypsa_ddf = energy_inflow[show_techs + [\"Others\"]].reset_index(drop=True)\n",
" pypsa_ddf = pd.concat([\n",
" pypsa_ddf[col].sort_values(ascending=False).reset_index(drop=True) for col in pypsa_ddf.columns\n",
" ], axis=1)\n",
"\n",
" axs[2,1].stackplot(range(len(pypsa_ddf)), *[pypsa_ddf[col].values for col in pypsa_ddf.columns],\n",
" labels=pypsa_ddf.columns)\n",
"\n",
" ylim_max = max([pypsa_ddf.max(axis=0).sum(), entsoe_ddf.max(axis=0).sum()])\n",
"\n",
" pypsa_ddf = energy_outflow.reset_index(drop=True)\n",
" pypsa_ddf = pd.concat([\n",
" pypsa_ddf[col].sort_values(ascending=True).reset_index(drop=True) for col in pypsa_ddf.columns\n",
" ], axis=1)\n",
"\n",
" axs[2,1].stackplot(range(len(pypsa_ddf)), *[pypsa_ddf[col].values for col in pypsa_ddf.columns],\n",
" colors=[\"seagreen\", \"royalblue\", \"gold\"],\n",
" labels=energy_outflow.columns)\n",
"\n",
" ylim_min = energy_outflow.min(axis=0).sum()\n",
"\n",
" for ax in axs[2,:2]:\n",
" ax.legend()\n",
" ax.set_ylim(ylim_min, ylim_max)\n",
"\n",
" pypsa_totals = pd.concat([energy_inflow[show_techs + [\"Others\"]], energy_outflow], axis=1).sum() \n",
"\n", "\n",
" entsoe_totals = entsoe_df.sum()\n", " entsoe_totals = entsoe_df.sum()\n",
" totals = pd.DataFrame(index=pypsa_totals.index)\n", " totals = pd.DataFrame(index=pypsa_totals.index) \n",
" \n",
" for tech in pypsa_totals.index:\n",
" if tech not in entsoe_totals.index:\n",
" entsoe_totals.loc[tech] = 0.\n",
"\n", "\n",
" totals[\"pypsa\"] = pypsa_totals\n", " totals[\"Pypsa\"] = pypsa_totals\n",
" totals[\"entsoe\"] = entsoe_totals\n", " totals[\"Entsoe\"] = entsoe_totals\n",
" entsoe_totals.loc[\"Import Export\"] = 0.0\n", " totals[\"Technology\"] = totals.index\n",
" totals[\"tech\"] = totals.index\n",
"\n", "\n",
" totals = pd.concat(\n", " totals = pd.concat([\n",
" [\n", " pd.DataFrame({\"Source\": [\"PyPSA\" for _ in range(len(pypsa_totals))],\n",
" pd.DataFrame(\n", " \"Technology\": pypsa_totals.index,\n",
" {\n", " \"Total Generation\": pypsa_totals.values,\n",
" \"kind\": [\"pypsa\" for _ in range(len(pypsa_totals))],\n", " }),\n",
" \"tech\": pypsa_totals.index,\n", " pd.DataFrame({\"Source\": [\"ENTSO-E\" for _ in range(len(entsoe_totals))],\n",
" \"total generation\": pypsa_totals.values,\n", " \"Technology\": entsoe_totals.index,\n",
" }\n", " \"Total Generation\": entsoe_totals.values,\n",
" ),\n", " }),], axis=0\n",
" pd.DataFrame(\n",
" {\n",
" \"kind\": [\"entsoe\" for _ in range(len(entsoe_totals))],\n",
" \"tech\": entsoe_totals.index,\n",
" \"total generation\": entsoe_totals.values,\n",
" }\n",
" ),\n",
" ],\n",
" axis=0,\n",
" )\n", " )\n",
"\n", "\n",
" sns.barplot(\n", " sns.barplot(data=totals, x=\"Technology\", y=\"Total Generation\", hue=\"Source\", ax=axs[2,2],\n",
" data=totals,\n", " palette=\"dark\", alpha=.6, edgecolor=\"k\")\n",
" x=\"tech\",\n", " \n",
" y=\"total generation\",\n", " axs[2,0].set_xlabel(\"Hours\")\n",
" hue=\"kind\",\n", " axs[2,1].set_xlabel(\"Hours\")\n",
" ax=axs[2, 2],\n", " axs[2,2].set_ylabel(\"Total Generation [GWh]\")\n",
" palette=\"dark\",\n", " axs[2,2].set_xticks(axs[2,2].get_xticks(), axs[2,2].get_xticklabels(), rotation=45, ha='right')\n",
" alpha=0.6,\n", "\n",
" edgecolor=\"k\",\n", " corrs = (\n",
" )\n", " energy_inflow\n",
" axs[2, 2].set_ylabel(\"Total Generation\")\n", " .corrwith(entsoe_df)\n",
" axs[2, 2].set_xticks(\n", " .drop(index=\"Others\")\n",
" axs[2, 2].get_xticks(), axs[2, 2].get_xticklabels(), rotation=45, ha=\"right\"\n", " .dropna()\n",
" .sort_values(ascending=False)\n",
" )\n", " )\n",
"\n", "\n",
" for col, ax in zip(corrs.index[:2].tolist() + [corrs.index[-1]], axs[3]):\n",
" ax.scatter(entsoe_df[col].values,\n",
" energy_inflow[col].values,\n",
" color=\"darkred\",\n",
" alpha=0.5,\n",
" s=20,\n",
" edgecolor=\"k\" \n",
" )\n",
" ax.set_title(f\"{col}; Pearson Corr {np.around(corrs.loc[col], decimals=4)}\")\n",
" ax.set_xlabel(\"ENTSO-E Generation [GW]\")\n",
" ax.set_ylabel(\"PyPSA-Eur Generation [GW]\")\n",
" \n",
" for ax in axs[:2].flatten():\n",
" ax.set_xlabel(\"Datetime\")\n",
"\n",
" \n",
" plt.tight_layout()\n", " plt.tight_layout()\n",
" plt.show()\n", " plt.show()"
"\n",
" if num == 7:\n",
" break\n",
"\n",
"\n",
"# df.to_csv(data_path / \"pypsa_data\" / (country+\".csv\"))"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"links = n.links.loc[\n",
" (n.links.bus0.str.contains(\"DE\") + n.links.bus1.str.contains(\"DE\")).astype(bool)\n",
"]\n",
"links = links.loc[links.carrier == \"DC\"].sum(axis=1)\n",
"n.links_t.p0[links.index.tolist()].resample(\"w\").sum().plot()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"german_origin = n.links.loc[links.index].bus0.str.contains(\"DE\")\n",
"german_destin = n.links.loc[links.index].bus1.str.contains(\"DE\")\n",
"\n",
"net_impexp = pd.concat(\n",
" (n.links_t.p0[german_origin.index], n.links_t.p0[german_destin.index]), axis=1\n",
").sum(axis=1)\n",
"\n",
"net_impexp.iloc[:200].plot()"
] ]
} }
], ],
"metadata": { "metadata": {
"kernelspec": { "kernelspec": {
"display_name": "", "display_name": "pypsa-eur",
"language": "python", "language": "python",
"name": "" "name": "python3"
}, },
"language_info": { "language_info": {
"codemirror_mode": { "codemirror_mode": {
@ -349,7 +438,7 @@
"name": "python", "name": "python",
"nbconvert_exporter": "python", "nbconvert_exporter": "python",
"pygments_lexer": "ipython3", "pygments_lexer": "ipython3",
"version": "3.8.0" "version": "3.10.10"
}, },
"orig_nbformat": 4 "orig_nbformat": 4
}, },