Flow Plot Example

Note

You can download this example as a Jupyter notebook or start it in interactive mode.

Flow Plot Example#

Here, we are going to import a network and plot the electricity flow

[1]:
import warnings

import cartopy.crs as ccrs
import matplotlib.pyplot as plt
import pandas as pd
from shapely.errors import ShapelyDeprecationWarning

import pypsa

warnings.filterwarnings("ignore", category=ShapelyDeprecationWarning)
plt.rc("figure", figsize=(10, 8))

Import and optimize a network#

[2]:
n = pypsa.examples.ac_dc_meshed(from_master=True)
n.optimize()
/tmp/ipykernel_1853/447566826.py:1: DeprecationWarning:

The 'update' and 'from_master' parameters are deprecated and do not have any effect. Example networks are always updated and retrieved for the current version.Deprecated in version 0.35 and will be removed in version 1.0.

INFO:pypsa.io:Retrieving network data from https://github.com/PyPSA/PyPSA/raw/master/examples/networks/ac-dc-meshed/ac-dc-meshed.nc.
INFO:pypsa.io:Imported network ac-dc-meshed.nc has buses, carriers, generators, global_constraints, lines, links, loads
WARNING:pypsa.consistency:The following lines have zero x, which could break the linear load flow:
Index(['2', '3', '4'], dtype='object', name='Line')
WARNING:pypsa.consistency:The following lines have zero r, which could break the linear load flow:
Index(['0', '1', '5', '6'], dtype='object', name='Line')
INFO:linopy.model: Solve problem using Highs solver
INFO:linopy.io: Writing time: 0.04s
INFO:linopy.constants: Optimization successful:
Status: ok
Termination condition: optimal
Solution: 188 primals, 468 duals
Objective: -3.47e+06
Solver model: available
Solver message: Optimal

INFO:pypsa.optimization.optimize:The shadow-prices of the constraints Generator-ext-p-lower, Generator-ext-p-upper, Line-ext-s-lower, Line-ext-s-upper, Link-ext-p-lower, Link-ext-p-upper, Kirchhoff-Voltage-Law were not assigned to the network.
Running HiGHS 1.10.0 (git hash: fd86653): Copyright (c) 2025 HiGHS under MIT licence terms
LP   linopy-problem-nkuwavbi has 468 rows; 188 cols; 1007 nonzeros
Coefficient ranges:
  Matrix [1e-02, 1e+00]
  Cost   [9e-03, 3e+03]
  Bound  [2e+07, 2e+07]
  RHS    [9e-01, 1e+03]
Presolving model
391 rows, 187 cols, 930 nonzeros  0s
305 rows, 101 cols, 1042 nonzeros  0s
Dependent equations search running on 22 equations with time limit of 1000.00s
Dependent equations search removed 0 rows and 0 nonzeros in 0.00s (limit = 1000.00s)
303 rows, 99 cols, 1058 nonzeros  0s
Presolve : Reductions: rows 303(-165); columns 99(-89); elements 1058(+51)
Solving the presolved LP
Using EKK dual simplex solver - serial
  Iteration        Objective     Infeasibilities num(sum)
          0    -2.1204510016e+07 Pr: 102(98953); Du: 0(4.73182e-11) 0s
        126    -3.4742560406e+06 Pr: 0(0) 0s
Solving the original LP from the solution after postsolve
Model name          : linopy-problem-nkuwavbi
Model status        : Optimal
Simplex   iterations: 126
Objective value     : -3.4742560406e+06
Relative P-D gap    :  1.0722555433e-15
HiGHS run time      :          0.00
Writing the solution to /tmp/linopy-solve-xu4qqe6d.sol
[2]:
('ok', 'optimal')

Get mean generator power by bus and carrier:

[3]:
gen = n.generators.assign(g=n.generators_t.p.mean()).groupby(["bus", "carrier"]).g.sum()

Plot the electricity flows:

[4]:
# links are not displayed for prettier output ('link_widths=0')
n.plot(
    bus_sizes=gen / 5e3,
    bus_colors={"gas": "indianred", "wind": "midnightblue"},
    margin=0.5,
    line_widths=0.1,
    line_flow="mean",
    link_widths=0,
)
plt.show()
/tmp/ipykernel_1853/4091188128.py:2: DeprecatedWarning:

plot is deprecated as of 0.34 and will be removed in 1.0. Use `n.plot.map()` as a drop-in replacement instead.

../_images/examples_flow-plot_7_1.png

Plot the electricity flows with a different projection and a colored map:

[5]:
# links are not displayed for prettier output ('link_widths=0')
n.plot(
    bus_sizes=gen / 5e3,
    bus_colors={"gas": "indianred", "wind": "midnightblue"},
    margin=0.5,
    line_widths=0.1,
    line_flow="mean",
    link_widths=0,
    projection=ccrs.EqualEarth(),
    color_geomap=True,
)
plt.show()
/tmp/ipykernel_1853/3522267303.py:2: DeprecatedWarning:

plot is deprecated as of 0.34 and will be removed in 1.0. Use `n.plot.map()` as a drop-in replacement instead.

../_images/examples_flow-plot_9_1.png

Set arbitrary values as flow argument using a specific level from the n.branches() MultiIndex:

[6]:
line_flow = pd.Series(10, index=n.branches().loc["Line"].index)
link_flow = pd.Series(10, index=n.branches().loc["Link"].index)
[7]:
line_flow
[7]:
name
0    10
1    10
2    10
3    10
4    10
5    10
6    10
dtype: int64
[8]:
# links are not displayed for prettier output ('link_widths=0')
n.plot(
    bus_sizes=gen / 5e3,
    bus_colors={"gas": "indianred", "wind": "midnightblue"},
    margin=0.5,
    line_flow=line_flow,
    link_flow=link_flow,
    line_widths=2.7,
    link_widths=0,
    projection=ccrs.EqualEarth(),
    color_geomap=True,
)
plt.show()
/tmp/ipykernel_1853/235926658.py:2: DeprecatedWarning:

plot is deprecated as of 0.34 and will be removed in 1.0. Use `n.plot.map()` as a drop-in replacement instead.

../_images/examples_flow-plot_13_1.png

Adjust link colors according to their mean load:

[9]:
# Pandas series with MultiIndex
# links are not displayed for prettier output ('link_widths=0')
collections = n.plot(
    bus_sizes=gen / 5e3,
    bus_colors={"gas": "indianred", "wind": "midnightblue"},
    margin=0.5,
    line_flow=line_flow,
    line_widths=2.7,
    link_widths=0,
    projection=ccrs.EqualEarth(),
    color_geomap=True,
    line_colors=n.lines_t.p0.mean().abs(),
)

plt.colorbar(
    collections["branches"]["Line"], fraction=0.04, pad=0.004, label="Flow in MW"
)
plt.show()
/tmp/ipykernel_1853/1394478391.py:3: DeprecatedWarning:

plot is deprecated as of 0.34 and will be removed in 1.0. Use `n.plot.map()` as a drop-in replacement instead.

../_images/examples_flow-plot_15_1.png