Skip to content

Commit 828a5ec

Browse files
committed
Add notebooks from MUSE2 repo, using helpers
1 parent 172c474 commit 828a5ec

5 files changed

Lines changed: 1711 additions & 19 deletions

File tree

.pre-commit-config.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ repos:
88
- id: end-of-file-fixer
99
- id: pretty-format-json
1010
args: [--autofix, --indent, '4', --no-sort]
11+
exclude: \.ipynb$
1112
- repo: https://github.com/macisamuele/language-formatters-pre-commit-hooks
1213
rev: v2.14.0
1314
hooks:

notebooks/capacity.ipynb

Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
{
2+
"cells": [
3+
{
4+
"cell_type": "markdown",
5+
"id": "0",
6+
"metadata": {},
7+
"source": [
8+
"# Calculating agent capacity\n",
9+
"\n",
10+
"This notebook contains example data processing using the output of the [`muse1_default`] example\n",
11+
"model.\n",
12+
"\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",
16+
"\n",
17+
"[`muse1_default`]: ../../examples/muse1_default/\n",
18+
"[output-format]: https://energysystemsmodellinglab.github.io/MUSE2/file_formats/output_files.html"
19+
]
20+
},
21+
{
22+
"cell_type": "code",
23+
"execution_count": null,
24+
"id": "1",
25+
"metadata": {},
26+
"outputs": [],
27+
"source": [
28+
"import sys\n",
29+
"import tomllib\n",
30+
"\n",
31+
"import pandas as pd\n",
32+
"\n",
33+
"sys.path.append(\"..\")\n",
34+
"\n",
35+
"from muse2_data_analysis.helpers import get_example_input_dir, get_example_output_dir\n",
36+
"\n",
37+
"input_dir = get_example_input_dir()\n",
38+
"output_dir = get_example_output_dir()\n",
39+
"\n",
40+
"with (input_dir / \"model.toml\").open(\"rb\") as f:\n",
41+
" model = tomllib.load(f)\n",
42+
"\n",
43+
"# We need to know the milestone years for processing the assets file\n",
44+
"years = model[\"milestone_years\"]"
45+
]
46+
},
47+
{
48+
"cell_type": "markdown",
49+
"id": "2",
50+
"metadata": {},
51+
"source": [
52+
"## Load and process output data\n",
53+
"\n",
54+
"We next load the output data. In this case, we want to calculate how much capacity was invested in\n",
55+
"different processes for different agents. This information can be found in the `assets.csv` output\n",
56+
"file.\n",
57+
"\n",
58+
"The `assets.csv` file contains information about different assets, including when they were\n",
59+
"commissioned and decommissioned as well as their capacity. To calculate the overall capacity for a\n",
60+
"given agent and process type, we have to process this data. Note that different assets owned by the\n",
61+
"same agent may have the same process ID if the agent has reinvested in the same process type in a\n",
62+
"different year."
63+
]
64+
},
65+
{
66+
"cell_type": "code",
67+
"execution_count": null,
68+
"id": "3",
69+
"metadata": {},
70+
"outputs": [],
71+
"source": [
72+
"# The assets.csv file contains info about which assets were invested in and when\n",
73+
"assets = pd.read_csv(output_dir / \"assets.csv\")\n",
74+
"\n",
75+
"# Assets with no decommission_year are effectively decommissioned after time horizon\n",
76+
"assets[\"decommission_year\"] = assets[\"decommission_year\"].fillna(years[-1] + 1)\n",
77+
"\n",
78+
"# Calculate capacity for each type of process for each agent\n",
79+
"capacity = pd.DataFrame()\n",
80+
"for year in years:\n",
81+
" active = assets[\n",
82+
" (year >= assets[\"commission_year\"]) & (year < assets[\"decommission_year\"])\n",
83+
" ]\n",
84+
"\n",
85+
" # This only works because each agent is responsible for one and only one commodity\n",
86+
" cap_sum = active.groupby([\"agent_id\", \"process_id\"])[\"capacity\"].sum().reset_index()\n",
87+
"\n",
88+
" df = pd.DataFrame(cap_sum)\n",
89+
" df[\"year\"] = year\n",
90+
"\n",
91+
" capacity = pd.concat([capacity, df])\n",
92+
"\n",
93+
"capacity"
94+
]
95+
},
96+
{
97+
"cell_type": "markdown",
98+
"id": "4",
99+
"metadata": {},
100+
"source": [
101+
"## Plot results\n",
102+
"\n",
103+
"Finally, we plot the results.\n",
104+
"\n",
105+
"Note that each of the agents has invested in only one process type; otherwise there would be\n",
106+
"multiple bars per plot here."
107+
]
108+
},
109+
{
110+
"cell_type": "code",
111+
"execution_count": null,
112+
"id": "5",
113+
"metadata": {},
114+
"outputs": [],
115+
"source": [
116+
"import matplotlib.pyplot as plt\n",
117+
"\n",
118+
"agents = capacity[\"agent_id\"].unique()\n",
119+
"_, axes = plt.subplots(1, len(agents))\n",
120+
"for ax, agent in zip(axes, agents):\n",
121+
" capacity[capacity[\"agent_id\"] == agent].pivot(\n",
122+
" index=\"year\", columns=\"process_id\", values=\"capacity\"\n",
123+
" ).plot(kind=\"bar\", ax=ax)\n",
124+
" ax.set_title(agent)\n",
125+
" ax.set_xlabel(\"Year\")\n",
126+
" ax.set_ylabel(\"Capacity\")\n",
127+
" ax.legend(title=\"Process\")"
128+
]
129+
}
130+
],
131+
"metadata": {
132+
"kernelspec": {
133+
"display_name": "muse2-data-analysis",
134+
"language": "python",
135+
"name": "python3"
136+
},
137+
"language_info": {
138+
"codemirror_mode": {
139+
"name": "ipython",
140+
"version": 3
141+
},
142+
"file_extension": ".py",
143+
"mimetype": "text/x-python",
144+
"name": "python",
145+
"nbconvert_exporter": "python",
146+
"pygments_lexer": "ipython3",
147+
"version": "3.14.2"
148+
}
149+
},
150+
"nbformat": 4,
151+
"nbformat_minor": 5
152+
}

notebooks/prices.ipynb

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
{
2+
"cells": [
3+
{
4+
"cell_type": "markdown",
5+
"id": "0",
6+
"metadata": {},
7+
"source": [
8+
"# Plotting commodity prices\n",
9+
"\n",
10+
"This notebook shows how to plot commodity prices, using the [`muse1_default`] example model.\n",
11+
"\n",
12+
"We first load the prices from the `commodity_prices.csv` output file.\n",
13+
"\n",
14+
"[`muse1_default`]: ../../examples/muse1_default/"
15+
]
16+
},
17+
{
18+
"cell_type": "code",
19+
"execution_count": null,
20+
"id": "1",
21+
"metadata": {},
22+
"outputs": [],
23+
"source": [
24+
"import sys\n",
25+
"\n",
26+
"import pandas as pd\n",
27+
"\n",
28+
"sys.path.append(\"..\")\n",
29+
"\n",
30+
"from muse2_data_analysis.helpers import get_example_output_dir\n",
31+
"\n",
32+
"output_dir = get_example_output_dir()\n",
33+
"prices = pd.read_csv(output_dir / \"commodity_prices.csv\")\n",
34+
"prices.head()"
35+
]
36+
},
37+
{
38+
"cell_type": "code",
39+
"execution_count": null,
40+
"id": "2",
41+
"metadata": {},
42+
"outputs": [],
43+
"source": [
44+
"from matplotlib import pyplot as plt\n",
45+
"\n",
46+
"COMMODITY_ID = \"heat\"\n",
47+
"\n",
48+
"# This won't work if there are multiple regions\n",
49+
"assert prices[\"region_id\"].nunique() == 1\n",
50+
"\n",
51+
"_, ax = plt.subplots()\n",
52+
"\n",
53+
"prices[prices[\"commodity_id\"] == COMMODITY_ID].pivot(\n",
54+
" index=\"milestone_year\", columns=\"time_slice\", values=\"price\"\n",
55+
").plot(kind=\"bar\", ax=ax)\n",
56+
"\n",
57+
"ax.set_xlabel(\"Milestone year\")\n",
58+
"ax.set_ylabel(\"Price\")\n",
59+
"ax.legend(title=\"Time slice\");"
60+
]
61+
}
62+
],
63+
"metadata": {
64+
"kernelspec": {
65+
"display_name": "muse2-data-analysis",
66+
"language": "python",
67+
"name": "python3"
68+
},
69+
"language_info": {
70+
"codemirror_mode": {
71+
"name": "ipython",
72+
"version": 3
73+
},
74+
"file_extension": ".py",
75+
"mimetype": "text/x-python",
76+
"name": "python",
77+
"nbconvert_exporter": "python",
78+
"pygments_lexer": "ipython3",
79+
"version": "3.14.2"
80+
}
81+
},
82+
"nbformat": 4,
83+
"nbformat_minor": 5
84+
}

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ authors = [
88
]
99
requires-python = ">=3.14"
1010

11-
dependencies = []
11+
dependencies = ["matplotlib>=3.10.8", "notebook>=7.5.2", "pandas>=3.0.0"]
1212

1313
[dependency-groups]
1414
dev = [

0 commit comments

Comments
 (0)