Skip to content

Statistics

PyPSA offers a variety of functions for plotting networks based on the statistics module. Line, bar and area charts can be plotted against any network metric, and plots can be created as either as static matplotlib figures or interactive plotly charts.

Static Plots

Various key metrics that can be calculated on any PyPSA network are described in the Statistics section. The plotting module lets you create plots of any of these metrics.

Info

The examples below are based on two networks: n_simple is based on a minimal three-node network, which is available via pypsa.examples.ac_dc_meshed, and n is the more complex hybrid scenario network from a recently published paper on carbon management. This network is also available in PyPSA via pypsa.examples.carbon_management.

Load the networks:

# Simple three-node network
>>> n_simple = pypsa.examples.ac_dc_meshed()
>>> n_simple
PyPSA Network 'AC-DC-Meshed'
----------------------------
Components:
 - Bus: 9
 - Carrier: 6
 - Generator: 6
 - GlobalConstraint: 1
 - Line: 7
 - Link: 4
 - Load: 6
Snapshots: 10
# Complex sector coupled network
>>> n = pypsa.examples.carbon_management()
>>> n
PyPSA Network 'Hybrid Scenario from https://www.nature.com/articles/s41560-025-01752-6'
---------------------------------------------------------------------------------------
Components:
 - Bus: 2164
 - Carrier: 89
 - Generator: 1489
 - GlobalConstraint: 4
 - Line: 157
 - Link: 6830
 - Load: 1357
 - StorageUnit: 106
 - Store: 1263
Snapshots: 168

Defaults

Many different statistics are available via the n.statistics accessor:

>>> n_simple.statistics.energy_balance()
component  carrier  bus_carrier
Generator  gas      AC              1465.27439
           wind     AC             31082.35370
Load       load     AC            -32547.62808
dtype: float64

Any of these metrics can also be used to create plots straight away:

>>> n_simple.statistics.energy_balance.plot()
Buses

The default plot type varies depending on which type typically makes the most sense for a given metric. For instance, n.statistics.energy_balance.plot() produces an area plot with snapshots on the x-axis, whereas n.statistics.installed_capacity.plot() produces a simple bar chart without a time dimension.

>>> n_simple.statistics.installed_capacity.plot()
Buses

Complex Networks

In principle, these standard plots can be created from any network. However, depending on factors such as network size, number of components and snapshots, the plot may be difficult to read and may require further customisation. If the default option is not useful, there are three options to get useful plots for more complex networks:

  1. The full static plot API is also available for interactive plots. This gives you more control over data selection and data can be more easily explored. See Interactive Plots.
  2. Plots are created using matplotlib and seaborn. This means that you can use all the customization options of these libraries to further customize the plot. See Customization with matplotlib and seaborn.
  3. The parameters that can be used to filter and aggregate data using base statistics methods can also be passed to plotting methods. See Customization based on statistics parameters.

All options are described in the following sections.

Plot Types

The basic plotting method (n.statistics.<metric>.plot()) is not very flexible, but useful for quick exploration. To gain more control over the plot, the according plot type method can be called directly. Any plot type can be used with any metric, although not all plots will be meaningful for all metrics.

For instance, energy balances can also be shown as a bar chart, ignoring the time dimension:

>>> n_simple.statistics.energy_balance.plot.bar()
Buses

Available Plot Types

The following plot types are available:

>>> n_simple.statistics.energy_balance.plot.area()
Buses

>>> n_simple.statistics.energy_balance.plot.bar()
Buses

>>> n_simple.statistics.energy_balance.plot.map()
Buses

>>> n_simple.statistics.energy_balance.plot.scatter()
Buses

>>> n_simple.statistics.energy_balance.plot.line()
Buses

>>> n_simple.statistics.energy_balance.plot.box()
Buses

>>> n_simple.statistics.energy_balance.plot.violin()
Buses

>>> n_simple.statistics.energy_balance.plot.histogram()
Buses

Customization

Customization with matplotlib and seaborn

All plot methods return a matplotlib figure object, a matplotlib axes object and a facet grid object. These can be used to customise the plot further. See the matplotlib documentation on matplotlib.figure, matplotlib.axes and the seaborn documentation on seaborn.FacetGrid.

>>> fig, ax, facet_col = n_simple.statistics.energy_balance.plot.area()
>>> fig.set_size_inches(12, 3)
>>> fig.suptitle("My Scenario", fontsize=12)
>>> ax.grid(True, alpha=0.5, linestyle="--")
>>> ax.set_xlabel("Time", fontsize=9)
>>> ax.set_ylabel("Energy Balance (MW)", fontsize=9)
Buses

Customization with statistics parameters

Parameters which are available in the statistics methods to filter and aggregate data can also be passed to the corresponding plotting methods. The full energy balance of the carbon management example network yields too many different carriers to be shown in a single plot. However, if we filter it down to include only buses with the 'AC' carrier, via the bus_carrier parameter from the statistics method, we can produce a meaningful plot.

>>> n.statistics.energy_balance.plot.area(bus_carrier="AC", figsize=(12, 3))
Buses

>>> n.statistics.energy_balance.plot.area(figsize=(10, 3))
Buses

Behind the scenes, each plotting method selects a different set of parameters to call the relevant statistics method. Therefore, the default value can be different for each plot type and metric. Most of these parameters can also be passed directly to the plotting method. Please refer to the Statistics for more details.

Tip

To decide which subset of data to show in your plot, it is often helpful to experiment with the relevant statistics method first to find the right parameters. Once you are happy with your selection, simply pass the parameters to the plotting method and the same selection will be applied. You can also pass them alongside all the other available plotting parameters. Check the API reference for details.

Interactive Plots

All the logic for static plots, using n.statistics.<metric>.plot.<plot_type>(), is mirrored for interactive plots. While the returned object and parameters may differ, you can usually simply replace plot with iplot to get an interactive version of the same plot. Behind the scenes, Plotly is used for the interactive plots and the returned object is a Plotly figure object. Check out the Plotly documentation for more details.

Examples

Simple Energy Balance Area Plot

>>> n_simple.statistics.energy_balance.iplot.area()

>>> n_simple.statistics.energy_balance.plot()
Buses

Carbon Network Energy Balance with bus carrier AC

>>> n.statistics.energy_balance.iplot.area(bus_carrier="AC")

>>> n.statistics.energy_balance.plot(bus_carrier="AC")
Buses

Full Carbon Network Energy Balance

>>> n.statistics.energy_balance.iplot.area()

>>> n.statistics.energy_balance.plot.area(figsize=(10, 3))
Buses