Skip to content

Commit e2c50f6

Browse files
authored
Merge pull request #84 from EnergySystemsModellingLab/75_notebooks
75 notebooks
2 parents a8f19c3 + 46a7f08 commit e2c50f6

4 files changed

Lines changed: 39 additions & 66 deletions

File tree

.github/workflows/ci.yml

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,12 @@ on:
99
workflow_call:
1010

1111
jobs:
12-
test_release:
13-
name: Latest MUSE2 release
14-
uses: ./.github/workflows/test-with-muse2.yml
15-
with:
16-
muse2_source: release
17-
secrets: inherit
12+
# test_release:
13+
# name: Latest MUSE2 release
14+
# uses: ./.github/workflows/test-with-muse2.yml
15+
# with:
16+
# muse2_source: release
17+
# secrets: inherit
1818

1919
test_main:
2020
name: Current MUSE2 main branch

.pre-commit-config.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ repos:
3030
rev: 0.9.1
3131
hooks:
3232
- id: nbstripout
33+
args: [--drop-empty-cells]
3334
- repo: https://github.com/pre-commit/mirrors-mypy
3435
rev: v2.1.0
3536
hooks:

notebooks/capacity.ipynb

Lines changed: 27 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,7 @@
1010
"This notebook contains example data processing using the output of an example\n",
1111
"model.\n",
1212
"\n",
13-
"Output files are mostly in CSV format. The format of output files is documented [here][output-format].\n",
14-
"\n",
15-
"We begin by loading the `model.toml` input file to get the list of milestone years.\n",
13+
"Output files are mostly in CSV format. The format of output files is documented [in MUSE2 documentation][output-format].\n",
1614
"\n",
1715
"[output-format]: https://energysystemsmodellinglab.github.io/MUSE2/file_formats/output_files.html"
1816
]
@@ -24,20 +22,11 @@
2422
"metadata": {},
2523
"outputs": [],
2624
"source": [
27-
"import tomllib\n",
28-
"\n",
2925
"import pandas as pd\n",
3026
"\n",
31-
"from muse2_data_analysis.helpers import get_example_input_dir, get_example_output_dir\n",
32-
"\n",
33-
"INPUT_DIR = get_example_input_dir()\n",
34-
"OUTPUT_DIR = get_example_output_dir()\n",
27+
"from muse2_data_analysis.helpers import get_example_output_dir\n",
3528
"\n",
36-
"with (INPUT_DIR / \"model.toml\").open(\"rb\") as f:\n",
37-
" model = tomllib.load(f)\n",
38-
"\n",
39-
"# We need to know the milestone years for processing the assets file\n",
40-
"years = model[\"milestone_years\"]"
29+
"OUTPUT_DIR = get_example_output_dir()"
4130
]
4231
},
4332
{
@@ -48,14 +37,13 @@
4837
"## Load and process output data\n",
4938
"\n",
5039
"We next load the output data. In this case, we want to calculate how much capacity was invested in\n",
51-
"different processes for different agents. This information can be found in the `assets.csv` output\n",
52-
"file.\n",
40+
"different processes for different agents. This information can be found in the `asset_capacities.csv`\n",
41+
"output file.\n",
5342
"\n",
54-
"The `assets.csv` file contains information about different assets, including when they were\n",
55-
"commissioned and decommissioned as well as their capacity. To calculate the overall capacity for a\n",
56-
"given agent and process type, we have to process this data. Note that different assets owned by the\n",
57-
"same agent may have the same process ID if the agent has reinvested in the same process type in a\n",
58-
"different year."
43+
"We also need some metadata, like the agent that manages the asset and the process the asset corresponds\n",
44+
"to. That time-independent information is contained in the `assets.csv` file. To calculate the overall\n",
45+
"capacity for a given agent and process type as a function of milestone year, we have to combine these\n",
46+
"two files and process the data."
5947
]
6048
},
6149
{
@@ -65,28 +53,15 @@
6553
"metadata": {},
6654
"outputs": [],
6755
"source": [
68-
"# The assets.csv file contains info about which assets were invested in and when\n",
6956
"assets = pd.read_csv(OUTPUT_DIR / \"assets.csv\")\n",
70-
"\n",
71-
"# Assets with no decommission_year are effectively decommissioned after time horizon\n",
72-
"assets[\"decommission_year\"] = assets[\"decommission_year\"].fillna(years[-1] + 1)\n",
73-
"\n",
74-
"# Calculate capacity for each type of process for each agent\n",
75-
"capacity = pd.DataFrame()\n",
76-
"for year in years:\n",
77-
" active = assets[\n",
78-
" (year >= assets[\"commission_year\"]) & (year < assets[\"decommission_year\"])\n",
79-
" ]\n",
80-
"\n",
81-
" # This only works because each agent is responsible for one and only one commodity\n",
82-
" cap_sum = active.groupby([\"agent_id\", \"process_id\"])[\"capacity\"].sum().reset_index()\n",
83-
"\n",
84-
" df = pd.DataFrame(cap_sum)\n",
85-
" df[\"year\"] = year\n",
86-
"\n",
87-
" capacity = pd.concat([capacity, df])\n",
88-
"\n",
89-
"capacity"
57+
"asset_capacities = pd.read_csv(OUTPUT_DIR / \"asset_capacities.csv\")\n",
58+
"\n",
59+
"merged = asset_capacities.merge(assets, on=[\"asset_id\", \"group_id\"])\n",
60+
"agg_capacities = merged.groupby([\"milestone_year\", \"agent_id\", \"process_id\"])[\n",
61+
" \"capacity\"\n",
62+
"].sum()\n",
63+
"agg_capacities_wide = agg_capacities.unstack([\"agent_id\", \"process_id\"], fill_value=0)\n",
64+
"agg_capacities_wide"
9065
]
9166
},
9267
{
@@ -96,10 +71,7 @@
9671
"source": [
9772
"## Plot results\n",
9873
"\n",
99-
"Finally, we plot the results.\n",
100-
"\n",
101-
"Note that each of the agents has invested in only one process type; otherwise there would be\n",
102-
"multiple bars per plot here."
74+
"Finally, we plot the results."
10375
]
10476
},
10577
{
@@ -111,22 +83,20 @@
11183
"source": [
11284
"import matplotlib.pyplot as plt\n",
11385
"\n",
114-
"agents = capacity[\"agent_id\"].unique()\n",
115-
"_, axes = plt.subplots(1, len(agents))\n",
86+
"agents = agg_capacities_wide.columns.get_level_values(\"agent_id\").unique()\n",
87+
"fig, axes = plt.subplots(1, len(agents), figsize=(4 * len(agents), 4))\n",
11688
"for ax, agent in zip(axes, agents):\n",
117-
" capacity[capacity[\"agent_id\"] == agent].pivot(\n",
118-
" index=\"year\", columns=\"process_id\", values=\"capacity\"\n",
119-
" ).plot(kind=\"bar\", ax=ax)\n",
120-
" ax.set_title(agent)\n",
121-
" ax.set_xlabel(\"Year\")\n",
122-
" ax.set_ylabel(\"Capacity\")\n",
123-
" ax.legend(title=\"Process\")"
89+
" agg_capacities_wide[agent].plot(\n",
90+
" kind=\"bar\", stacked=True, ax=ax, title=agent, xlabel=\"Year\", ylabel=\"Capacity\"\n",
91+
" )\n",
92+
"\n",
93+
"plt.tight_layout()"
12494
]
12595
}
12696
],
12797
"metadata": {
12898
"kernelspec": {
129-
"display_name": "muse2-data-analysis",
99+
"display_name": "Python 3 (ipykernel)",
130100
"language": "python",
131101
"name": "python3"
132102
},
@@ -140,7 +110,7 @@
140110
"name": "python",
141111
"nbconvert_exporter": "python",
142112
"pygments_lexer": "ipython3",
143-
"version": "3.14.2"
113+
"version": "3.14.6"
144114
}
145115
},
146116
"nbformat": 4,

notebooks/prices.ipynb

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,13 +50,15 @@
5050
"\n",
5151
"ax.set_xlabel(\"Milestone year\")\n",
5252
"ax.set_ylabel(\"Price\")\n",
53-
"ax.legend(title=\"Time slice\");"
53+
"ax.legend(\n",
54+
" title=\"Time slice\", bbox_to_anchor=(1.05, 1), loc=\"upper left\", borderaxespad=0.0\n",
55+
");"
5456
]
5557
}
5658
],
5759
"metadata": {
5860
"kernelspec": {
59-
"display_name": "muse2-data-analysis",
61+
"display_name": "Python 3 (ipykernel)",
6062
"language": "python",
6163
"name": "python3"
6264
},
@@ -70,7 +72,7 @@
7072
"name": "python",
7173
"nbconvert_exporter": "python",
7274
"pygments_lexer": "ipython3",
73-
"version": "3.14.2"
75+
"version": "3.14.6"
7476
}
7577
},
7678
"nbformat": 4,

0 commit comments

Comments
 (0)