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()
WARNING:pypsa.io:Importing network from PyPSA version v0.17.1 while current version is v0.31.0. Read the release notes at https://pypsa.readthedocs.io/en/latest/release_notes.html to prepare your network for import.
INFO:pypsa.io:Imported network ac-dc-meshed.nc has buses, carriers, generators, global_constraints, lines, links, loads
WARNING:pypsa.consistency:The following links have carriers which are not defined:
Index(['Norwich Converter', 'Norway Converter', 'Bremen Converter', 'DC link'], dtype='object', name='Link')
WARNING:pypsa.consistency:The following lines have carriers which are not defined:
Index(['0', '1', '2', '3', '4', '5', '6'], dtype='object', name='Line')
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')
WARNING:pypsa.consistency:The following buses have carriers which are not defined:
Index(['London', 'Norwich', 'Norwich DC', 'Manchester', 'Bremen', 'Bremen DC',
       'Frankfurt', 'Norway', 'Norway DC'],
      dtype='object', name='Bus')
WARNING:pypsa.consistency:The following links have carriers which are not defined:
Index(['Norwich Converter', 'Norway Converter', 'Bremen Converter', 'DC link'], dtype='object', name='Link')
WARNING:pypsa.consistency:The following lines have carriers which are not defined:
Index(['0', '1', '2', '3', '4', '5', '6'], dtype='object', name='Line')
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')
WARNING:pypsa.consistency:The following buses have carriers which are not defined:
Index(['London', 'Norwich', 'Norwich DC', 'Manchester', 'Bremen', 'Bremen DC',
       'Frankfurt', 'Norway', 'Norway DC'],
      dtype='object', name='Bus')
/home/docs/checkouts/readthedocs.org/user_builds/pypsa/envs/latest/lib/python3.12/site-packages/linopy/common.py:147: UserWarning: coords for dimension(s) ['Generator'] is not aligned with the pandas object. Previously, the indexes of the pandas were ignored and overwritten in these cases. Now, the pandas object's coordinates are taken considered for alignment.
  warn(
INFO:linopy.model: Solve problem using Highs solver
INFO:linopy.io: Writing time: 0.07s
INFO:linopy.solvers:Log file at /tmp/highs.log
INFO:linopy.constants: Optimization successful:
Status: ok
Termination condition: optimal
Solution: 188 primals, 474 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.7.2 (git hash: 184e327): Copyright (c) 2024 HiGHS under MIT licence terms
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
303 rows, 99 cols, 1058 nonzeros  0s
Presolve : Reductions: rows 303(-171); columns 99(-89); elements 1058(-9)
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   status      : Optimal
Simplex   iterations: 126
Objective value     : -3.4742560406e+06
HiGHS run time      :          0.00
Writing the solution to /tmp/linopy-solve-e2ja4fw_.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,
    flow="mean",
    line_widths=0.1,
    link_widths=0,
)
plt.show()
/home/docs/checkouts/readthedocs.org/user_builds/pypsa/envs/latest/lib/python3.12/site-packages/cartopy/mpl/feature_artist.py:144: UserWarning: facecolor will have no effect as it has been defined as "never".
  warnings.warn('facecolor will have no effect as it has been '
../_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,
    flow="mean",
    line_widths=0.1,
    link_widths=0,
    projection=ccrs.EqualEarth(),
    color_geomap=True,
)
plt.show()
/home/docs/checkouts/readthedocs.org/user_builds/pypsa/envs/latest/lib/python3.12/site-packages/cartopy/mpl/feature_artist.py:144: UserWarning: facecolor will have no effect as it has been defined as "never".
  warnings.warn('facecolor will have no effect as it has been '
../_images/examples_flow-plot_9_1.png

Set arbitrary values as flow argument using the MultiIndex of n.branches():

[6]:
flow = pd.Series(10, index=n.branches().index)
[7]:
flow
[7]:
component  name
Line       0                    10
           1                    10
           2                    10
           3                    10
           4                    10
           5                    10
           6                    10
Link       Norwich Converter    10
           Norway Converter     10
           Bremen Converter     10
           DC link              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,
    flow=flow,
    line_widths=2.7,
    link_widths=0,
    projection=ccrs.EqualEarth(),
    color_geomap=True,
)
plt.show()
/home/docs/checkouts/readthedocs.org/user_builds/pypsa/envs/latest/lib/python3.12/site-packages/cartopy/mpl/feature_artist.py:144: UserWarning: facecolor will have no effect as it has been defined as "never".
  warnings.warn('facecolor will have no effect as it has been '
../_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')
collection = n.plot(
    bus_sizes=gen / 5e3,
    bus_colors={"gas": "indianred", "wind": "midnightblue"},
    margin=0.5,
    flow=flow,
    line_widths=2.7,
    link_widths=0,
    projection=ccrs.EqualEarth(),
    color_geomap=True,
    line_colors=n.lines_t.p0.mean().abs(),
)

plt.colorbar(collection[2], fraction=0.04, pad=0.004, label="Flow in MW")
plt.show()
/home/docs/checkouts/readthedocs.org/user_builds/pypsa/envs/latest/lib/python3.12/site-packages/cartopy/mpl/feature_artist.py:144: UserWarning: facecolor will have no effect as it has been defined as "never".
  warnings.warn('facecolor will have no effect as it has been '
../_images/examples_flow-plot_15_1.png