Skip to content

Commit

Permalink
init sankey
Browse files Browse the repository at this point in the history
  • Loading branch information
mabudz committed Jan 7, 2024
1 parent d671101 commit 9656c81
Show file tree
Hide file tree
Showing 3 changed files with 188 additions and 0 deletions.
1 change: 1 addition & 0 deletions message_ix/report/__init__.py
Expand Up @@ -141,6 +141,7 @@
"message::costs",
"message::emissions",
),
("message::sankey", "concat", "out::pyam", "in::pyam"),
)


Expand Down
25 changes: 25 additions & 0 deletions message_ix/util/__init__.py
Expand Up @@ -6,6 +6,7 @@
import pandas as pd
from ixmp.backend import ItemType
from pandas.api.types import is_scalar
from pyam.utils import get_variable_components as gvc

from message_ix.core import Scenario
from message_ix.models import MACRO, MESSAGE
Expand Down Expand Up @@ -232,3 +233,27 @@ def expand_dims(scenario: Scenario, name, **data):

# Add the expanded data
scenario.add_par(name, new_data)

def sankey_mapper(df, year, region, flows_not_needed=[], variables_not_needed = []):

df_filtered = df.filter(
region=region+'*',
year=year)

mapping = {}
for var in df_filtered['variable']:
if gvc(var, 0) == 'in':
mapping[var] = (gvc(var, [1,2], join=True), gvc(var, [3,4], join=True))
if gvc(var, 0) == 'out':
mapping[var] = (gvc(var, [3,4], join=True), gvc(var, [1,2], join=True))



for k in mapping.keys():
for flow in flows_not_needed:
if flow in k:
variables_not_needed.append(k)
for var in variables_not_needed:
del mapping[var]

return mapping
162 changes: 162 additions & 0 deletions tutorial/westeros/westeros_sankey.ipynb
@@ -0,0 +1,162 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Westeros Tutorial - Introducing Sankey diagrams\n",
"\n",
"Sankey diagrams are a useful technique to visualize energy flow accounts.\n",
"\n",
"This tutorial introduces the sankey feature provided by the ``pyam`` packages.\n",
"\n",
"\n",
"**Pre-requisites**\n",
"- You have the *MESSAGEix* framework installed and working\n",
" In particular, you should have installed ``message_ix``, ``pyam``, and ``plotly``\n",
"- Complete tutorial Part 1 (``westeros_baseline.ipynb``) and Introducing Reporting (``westeros_report.ipynb``)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from message_ix.report import Reporter\n",
"import ixmp\n",
"import message_ix\n",
"\n",
"mp = ixmp.Platform()\n",
"scenario = message_ix.Scenario(mp, model=\"Westeros Electrified\", scenario=\"baseline\")\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Remove any existing solution\n",
"try:\n",
" scenario.remove_solution()\n",
"except ValueError:\n",
" pass\n",
"\n",
"scenario.solve()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Create the reporter object. (Since \"-\" is not a unit, we replace it by \"\".)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"rep = Reporter.from_scenario(scenario)\n",
"\n",
"rep.configure(units={\"replace\": {\"-\": \"\"}})\n",
"\n",
"\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Use the `message::sankey` reporter option to generate a pyam.dataframe including the reqiured input (`in::pyam`) and output flows (`out::pyam`) in iamc format.\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"df=rep.get(\"message::sankey\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The utility function `sankey_mapper(df, year, region, flows_not_needed=[], variables_not_needed=[])` can be used to create the required mapping for the `plot.sankey()` function of the `pyam` package.\n",
"\n",
"In some models it might be necessary to exclude variables and flow to get meaningful sankey diagrams. But let´s try with all!"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"mapping=message_ix.util.sankey_mapper(df,year=700,region=\"Westeros\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The pyam function `plot.sankey(mapping)`returns a plotly sankey figure object that can be further modified.\n",
"\n",
"To plot it as an interactive diagram in your web browser, you can do the following."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"import plotly.offline as pof\n",
"fig = df.filter(year=700).plot.sankey(mapping=mapping)\n",
"pof.plot(fig) # opens a new window in your browser"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Do not forget to close the database ;-) "
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"mp.close_db()"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "messageix",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.8.18"
},
"orig_nbformat": 4
},
"nbformat": 4,
"nbformat_minor": 2
}

0 comments on commit 9656c81

Please sign in to comment.