Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -156,4 +156,7 @@ examples/exergoeconomic_analysis/heatpump/
examples/opt_examples/

# macOS
.DS_Store
.DS_Store
# Generated visualization example outputs
examples/visualization/*.html
examples/visualization/*.png
18 changes: 18 additions & 0 deletions docs/examples.rst
Original file line number Diff line number Diff line change
Expand Up @@ -125,3 +125,21 @@ In the following example, we demonstrate how to extend the exergy analysis with

Exergoeconomic analysis with manually defined component investment costs and
input stream specific costs.

In the following example, we demonstrate how to visualize the results of an exergy analysis with Sankey and waterfall diagrams.

.. toctree::
:maxdepth: 1
:hidden:

examples/visualization.rst

.. card::
:link: examples_visualization_label
:link-type: ref

**Visualization**
^^^

Interactive Sankey diagrams of the exergy flows and waterfall diagrams of
the exergy destruction per component for the three example systems.
128 changes: 128 additions & 0 deletions docs/examples/visualization.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
.. _examples_visualization_label:

*************
Visualization
*************

ExerPy can visualize the results of a completed exergy analysis as an
interactive Sankey diagram of all exergy flows and as a waterfall diagram of
the exergy destruction per component. The plotting libraries are an optional
dependency, install them with:

.. code-block:: bash

pip install exerpy[viz]

The examples below build the diagrams from the exported analysis results of
the three example systems, so no simulator is required to run them, e.g.:

.. code-block:: bash

python examples/visualization/ccpp_diagrams.py

Sankey diagram
==============

:code:`plot_sankey` renders the exergy flows between all components of the
system together with four terminal nodes for the exergetic fuel (E_F), product
(E_P), destruction (E_D) and loss (E_L). If a fuel, product or loss definition
contains both inputs and outputs, an intermediate "net" node displays the
gross flows next to the net value. The most important options are:

- :code:`mode` – level of detail of the material links: :code:`1` shows the
total exergy flow E per connection, :code:`2` splits each material link into
physical and chemical exergy (requires chemical exergy), and :code:`3`
splits into thermal, mechanical and chemical exergy (requires
:code:`split_physical_exergy=True`).
- :code:`collapse_passthroughs` – hides pure pass-through components
(by default the :code:`CycleCloser`).
- :code:`groups` – aggregates several components into a single node and hides
the connections between them, e.g. to represent a subsystem.
- :code:`node_colors` – overrides the color of individual component nodes.
Link colors are assigned automatically based on the type of flow (power,
heat, or material by fluid).
- :code:`output_path` – exports the interactive diagram to an HTML file.

Waterfall diagram
=================

:code:`plot_exergy_waterfall` (Matplotlib) and
:code:`plot_exergy_waterfall_plotly` (interactive Plotly variant) display the
exergy destruction per component as percentages of the total fuel exergy, from
the exergetic fuel (100 %) down to the exergetic product. The bar colors can
be customized with the :code:`colors` dict using the keys :code:`"fuel"`,
:code:`"destruction"`, :code:`"loss"` and :code:`"product"`.

Examples
========

.. tab-set::

.. tab-item:: CCPP

1. **Load the results and run the analysis**

.. literalinclude:: /../examples/visualization/ccpp_diagrams.py
:language: python
:start-after: [analysis_section]
:end-before: [sankey_section]

2. **Create the Sankey diagrams**

.. literalinclude:: /../examples/visualization/ccpp_diagrams.py
:language: python
:start-after: [sankey_section]
:end-before: [waterfall_section]

3. **Create the waterfall diagrams**

.. literalinclude:: /../examples/visualization/ccpp_diagrams.py
:language: python
:start-after: [waterfall_section]
:end-before: [show_section]

.. tab-item:: Heat Pump

1. **Load the results and run the analysis**

.. literalinclude:: /../examples/visualization/hp_diagrams.py
:language: python
:start-after: [analysis_section]
:end-before: [sankey_section]

2. **Create the Sankey diagrams**

.. literalinclude:: /../examples/visualization/hp_diagrams.py
:language: python
:start-after: [sankey_section]
:end-before: [waterfall_section]

3. **Create the waterfall diagrams**

.. literalinclude:: /../examples/visualization/hp_diagrams.py
:language: python
:start-after: [waterfall_section]
:end-before: [show_section]

.. tab-item:: CGAM

1. **Load the results and run the analysis**

.. literalinclude:: /../examples/visualization/cgam_diagrams.py
:language: python
:start-after: [analysis_section]
:end-before: [sankey_section]

2. **Create the Sankey diagrams**

.. literalinclude:: /../examples/visualization/cgam_diagrams.py
:language: python
:start-after: [sankey_section]
:end-before: [waterfall_section]

3. **Create the waterfall diagrams**

.. literalinclude:: /../examples/visualization/cgam_diagrams.py
:language: python
:start-after: [waterfall_section]
:end-before: [show_section]
75 changes: 75 additions & 0 deletions examples/visualization/ccpp_diagrams.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
"""
Sankey and waterfall diagrams for the combined cycle power plant (ccpp) example.

The script loads the exported exergy analysis results, so no simulator is
required to run it:

python examples/visualization/ccpp_diagrams.py

The interactive diagrams are written as HTML files next to this script and
opened in the default browser (pass --no-show to only write the files).
"""

import sys
import webbrowser
from pathlib import Path

from exerpy import ExergyAnalysis

HERE = Path(__file__).parent

# [analysis_section]
ean = ExergyAnalysis.from_json(str(HERE / ".." / "exergy_analysis" / "ccpp" / "ccpp_tespy.json"))

fuel = {"inputs": ["1", "3"], "outputs": []}
product = {"inputs": ["e15", "h1"], "outputs": []}
loss = {"inputs": ["8", "15"], "outputs": ["14"]}

ean.analyse(E_F=fuel, E_P=product, E_L=loss)
# [sankey_section]
# Mode 1: one link per connection carrying the total exergy flow E.
ean.plot_sankey(
mode=1,
title="CCPP – Sankey diagram (total exergy)",
output_path=str(HERE / "ccpp_sankey_total.html"),
)

# Mode 2: material links are split into physical (E_PH) and chemical (E_CH)
# exergy. Requires an analysis with chemical exergy enabled.
ean.plot_sankey(
mode=2,
title="CCPP – Sankey diagram (physical + chemical exergy)",
output_path=str(HERE / "ccpp_sankey_split.html"),
)

# Components can be aggregated into groups and nodes can be colored
# individually. Links inside a group are hidden.
ean.plot_sankey(
groups={"HRSG": ["ECO", "EVA", "SH", "drum", "drum pump"]},
node_colors={"CC": "#C62828", "GT": "#388E3C"},
title="CCPP – Sankey diagram (grouped heat recovery steam generator)",
output_path=str(HERE / "ccpp_sankey_grouped.html"),
)
# [waterfall_section]
# Interactive plotly variant. Bar colors can be customized via the `colors`
# dict with the keys "fuel", "destruction", "loss" and "product".
fig = ean.plot_exergy_waterfall_plotly(title="CCPP – Exergy waterfall", show_plot=False)
fig.write_html(HERE / "ccpp_waterfall.html")

# Static matplotlib variant of the same diagram, exported as PNG.
fig, ax = ean.plot_exergy_waterfall(title="CCPP – Exergy waterfall", show_plot=False)
fig.savefig(HERE / "ccpp_waterfall.png", dpi=150, bbox_inches="tight")
# [show_section]
html_files = [
HERE / "ccpp_sankey_total.html",
HERE / "ccpp_sankey_split.html",
HERE / "ccpp_sankey_grouped.html",
HERE / "ccpp_waterfall.html",
]

for path in html_files + [HERE / "ccpp_waterfall.png"]:
print(f"written: {path}")

if "--no-show" not in sys.argv:
for path in html_files:
webbrowser.open(path.resolve().as_uri())
73 changes: 73 additions & 0 deletions examples/visualization/cgam_diagrams.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
"""
Sankey and waterfall diagrams for the CGAM example.

The script loads the exported exergy analysis results, so no simulator is
required to run it:

python examples/visualization/cgam_diagrams.py

The interactive diagrams are written as HTML files next to this script and
opened in the default browser (pass --no-show to only write the files).
"""

import sys
import webbrowser
from pathlib import Path

from exerpy import ExergyAnalysis

HERE = Path(__file__).parent

# [analysis_section]
ean = ExergyAnalysis.from_json(str(HERE / ".." / "exergy_analysis" / "cgam" / "cgam_tespy.json"))

fuel = {"inputs": ["1", "10"], "outputs": []}
product = {"inputs": ["e3", "9"], "outputs": ["8"]}
loss = {"inputs": ["7"], "outputs": []}

ean.analyse(E_F=fuel, E_P=product, E_L=loss)
# [sankey_section]
# Mode 1: one link per connection carrying the total exergy flow E. Since the
# product definition has inputs and outputs, an intermediate "E_P net" node
# shows the gross product flows next to the net product.
ean.plot_sankey(
mode=1,
title="CGAM – Sankey diagram (total exergy)",
output_path=str(HERE / "cgam_sankey_total.html"),
)

# Mode 2: material links are split into physical (E_PH) and chemical (E_CH)
# exergy. Requires an analysis with chemical exergy enabled.
ean.plot_sankey(
mode=2,
title="CGAM – Sankey diagram (physical + chemical exergy)",
output_path=str(HERE / "cgam_sankey_split.html"),
)

# Group the heat recovery steam generator into a single node.
ean.plot_sankey(
groups={"HRSG": ["EV", "PH", "DRUM"]},
node_colors={"CC": "#C62828", "EXP": "#388E3C"},
title="CGAM – Sankey diagram (grouped heat recovery steam generator)",
output_path=str(HERE / "cgam_sankey_grouped.html"),
)
# [waterfall_section]
fig = ean.plot_exergy_waterfall_plotly(title="CGAM – Exergy waterfall", show_plot=False)
fig.write_html(HERE / "cgam_waterfall.html")

fig, ax = ean.plot_exergy_waterfall(title="CGAM – Exergy waterfall", show_plot=False)
fig.savefig(HERE / "cgam_waterfall.png", dpi=150, bbox_inches="tight")
# [show_section]
html_files = [
HERE / "cgam_sankey_total.html",
HERE / "cgam_sankey_split.html",
HERE / "cgam_sankey_grouped.html",
HERE / "cgam_waterfall.html",
]

for path in html_files + [HERE / "cgam_waterfall.png"]:
print(f"written: {path}")

if "--no-show" not in sys.argv:
for path in html_files:
webbrowser.open(path.resolve().as_uri())
64 changes: 64 additions & 0 deletions examples/visualization/hp_diagrams.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
"""
Sankey and waterfall diagrams for the air source heat pump example.

The script loads the exported exergy analysis results, so no simulator is
required to run it:

python examples/visualization/hp_diagrams.py

The interactive diagrams are written as HTML files next to this script and
opened in the default browser (pass --no-show to only write the files).
"""

import sys
import webbrowser
from pathlib import Path

from exerpy import ExergyAnalysis

HERE = Path(__file__).parent

# [analysis_section]
ean = ExergyAnalysis.from_json(str(HERE / ".." / "exergy_analysis" / "heatpump" / "hp_tespy.json"))

fuel = {"inputs": ["e1"], "outputs": []}
product = {"inputs": ["23"], "outputs": ["21"]}
loss = {"inputs": ["13"], "outputs": ["11"]}

ean.analyse(E_F=fuel, E_P=product, E_L=loss)
# [sankey_section]
# The heat pump analysis runs without chemical exergy, so only mode 1 is
# available. Product and loss definitions both have inputs and outputs, so the
# diagram shows intermediate "E_P net" and "E_L net" nodes.
ean.plot_sankey(
mode=1,
title="Heat pump – Sankey diagram (total exergy)",
output_path=str(HERE / "hp_sankey_total.html"),
)

# Group the electric drives into a single node.
ean.plot_sankey(
groups={"Drives": ["electricity distribution", "MOT1", "MOT2", "MOT3"]},
node_colors={"COMP": "#C62828", "COND": "#388E3C"},
title="Heat pump – Sankey diagram (grouped drives)",
output_path=str(HERE / "hp_sankey_grouped.html"),
)
# [waterfall_section]
fig = ean.plot_exergy_waterfall_plotly(title="Heat pump – Exergy waterfall", show_plot=False)
fig.write_html(HERE / "hp_waterfall.html")

fig, ax = ean.plot_exergy_waterfall(title="Heat pump – Exergy waterfall", show_plot=False)
fig.savefig(HERE / "hp_waterfall.png", dpi=150, bbox_inches="tight")
# [show_section]
html_files = [
HERE / "hp_sankey_total.html",
HERE / "hp_sankey_grouped.html",
HERE / "hp_waterfall.html",
]

for path in html_files + [HERE / "hp_waterfall.png"]:
print(f"written: {path}")

if "--no-show" not in sys.argv:
for path in html_files:
webbrowser.open(path.resolve().as_uri())
Loading
Loading