Key Concepts in PyPSA#
Individual learning outcomes#
Get overall understanding on the core building blocks used in PyPSA
Understand the key functional elements of a PyPSA model
PyPSA stands for Python for Power System Analysis.
PyPSA is an open source Python package for simulating and optimising modern energy systems that include features such as
conventional generators with unit commitment (ramp-up, ramp-down, start-up, shut-down),
time-varying wind and solar generation,
energy storage with efficiency losses and inflow/spillage for hydroelectricity
coupling to other energy sectors (electricity, transport, heat, industry),
conversion between energy carriers (e.g. electricity to hydrogen),
transmission networks (AC, DC, other fuels)
PyPSA can be used for a variety of problem types (e.g. electricity market modelling, long-term investment planning, transmission network expansion planning), and is designed to scale well with large networks and long time series.
Compared to building power system by hand in linopy, PyPSA does the following things for you:
manage data inputs in standardised format
build standardised optimisation problem
communicate with the solver(s)
retrieve and process optimisation results
manage data outputs in standardised format
The documentation describes it as follows:
PyPSA is an open-source Python framework for optimising and simulating modern power and energy systems that include features such as conventional generators with unit commitment, variable wind and solar generation, hydro-electricity, inter-temporal storage, coupling to other energy sectors, elastic demands, and linearised power flow with loss approximations in DC and AC networks. PyPSA is designed to scale well with large networks and long time series. It is made for researchers, planners and utilities with basic coding aptitude who need a fast, easy-to-use and transparent tool for power and energy system analysis.
Note
Documentation for PyPSA is available at https://docs.pypsa.org including hand-ons examples.
Basic Structure#
Component |
Description |
|---|---|
Container for all components. |
|
Node where components attach. |
|
Energy carrier or technology (e.g. electricity, hydrogen, gas, coal, oil, biomass, on-/offshore wind, solar). Can track properties such as specific carbon dioxide emissions or nice names and colors for plots. |
|
Energy consumer (e.g. electricity demand). |
|
Generator (e.g. power plant, wind turbine, PV panel). |
|
Power distribution and transmission lines (overhead and cables). |
|
Links connect two buses with controllable energy flow, direction-control and losses. They can be used to model:
|
|
Storage with fixed nominal energy-to-power ratio. |
|
Constraints affecting many components at once, such as emission limits. |
|
Storage with separately extendable energy capacity. |
Note
Links in the table lead to documentation for each component.

Warning
Per unit values of voltage and impedance are used internally for network calculations. It is assumed internally that the base power is 1 MW.
From structured data to optimisation#
The design principle of PyPSA is that each component is associated with a set of variables and constraints that will be added to the optimisation model based on the input data stored for the components.
For an hourly electricity market simulation, PyPSA will solve an optimisation problem that looks like this
such that
Decision variables:
\(g_{i,s,t}\) is the generator dispatch at bus \(i\), technology \(s\), time step \(t\),
\(f_{\ell,t}\) is the power flow in line \(\ell\),
\(g_{i,r,t,\text{dis-/charge}}\) denotes the charge and discharge of storage unit \(r\) at bus \(i\) and time step \(t\),
\(e_{i,r,t}\) is the state of charge of storage \(r\) at bus \(i\) and time step \(t\).
Parameters:
\(o_{i,s}\) is the marginal generation cost of technology \(s\) at bus \(i\),
\(x_\ell\) is the reactance of transmission line \(\ell\),
\(K_{i\ell}\) is the incidence matrix,
\(C_{\ell c}\) is the cycle matrix,
\(G_{i,s}\) is the nominal capacity of the generator of technology \(s\) at bus \(i\),
\(F_{\ell}\) is the rating of the transmission line \(\ell\),
\(E_{i,r}\) is the energy capacity of storage \(r\) at bus \(i\),
\(\eta^{0/1/2}_{i,r,t}\) denote the standing (0), charging (1), and discharging (2) efficiencies.
Note
For a full reference to the optimisation problem description, see https://docs.pypsa.org/latest/user-guide/optimization/overview/
Simple example#
We’ll build a strongly simplified model building using PyPSA components as building blocks
#import pandas as pd
import pypsa
#pypsa.options.params.optimize.include_objective_constant = True
---------------------------------------------------------------------------
ModuleNotFoundError Traceback (most recent call last)
Cell In[1], line 2
1 #import pandas as pd
----> 2 import pypsa
3 #pypsa.options.params.optimize.include_objective_constant = True
File ~/miniconda3/envs/pypsa-zambia-workshops/lib/python3.13/site-packages/pypsa/__init__.py:21
13 __copyright__ = (
14 "Copyright 2015-2025 PyPSA Developers, see https://docs.pypsa.org/latest/contributing/contributors.html, "
15 "MIT License"
16 )
19 from typing import NoReturn
---> 21 from pypsa import (
22 clustering,
23 common,
24 components,
25 costs,
26 descriptors,
27 examples,
28 geo,
29 optimization,
30 plot,
31 statistics,
32 )
33 from pypsa._options import (
34 option_context,
35 options,
36 )
37 from pypsa.collection import NetworkCollection
File ~/miniconda3/envs/pypsa-zambia-workshops/lib/python3.13/site-packages/pypsa/examples.py:19
16 from platformdirs import user_cache_dir
18 from pypsa._options import options
---> 19 from pypsa.networks import Network
20 from pypsa.version import __version_base__
22 logger = logging.getLogger(__name__)
File ~/miniconda3/envs/pypsa-zambia-workshops/lib/python3.13/site-packages/pypsa/networks.py:29
25 from pathlib import Path
27 import functools
---> 29 import linopy
30 import numpy as np
31 import pandas as pd
File ~/miniconda3/envs/pypsa-zambia-workshops/lib/python3.13/site-packages/linopy/__init__.py:21
19 from linopy.expressions import LinearExpression, QuadraticExpression, merge
20 from linopy.io import read_netcdf
---> 21 from linopy.model import Model, Variable, Variables, available_solvers
22 from linopy.objective import Objective
23 from linopy.remote import OetcHandler, RemoteHandler
File ~/miniconda3/envs/pypsa-zambia-workshops/lib/python3.13/site-packages/linopy/model.py:63
61 from linopy.matrices import MatrixAccessor
62 from linopy.objective import Objective
---> 63 from linopy.remote import OetcHandler, RemoteHandler
64 from linopy.solver_capabilities import SolverFeature, solver_supports
65 from linopy.solvers import (
66 IO_APIS,
67 available_solvers,
68 )
File ~/miniconda3/envs/pypsa-zambia-workshops/lib/python3.13/site-packages/linopy/remote/__init__.py:11
1 """
2 Remote execution handlers for linopy models.
3
(...) 8 - OetcHandler: Cloud-based execution via OET Cloud service
9 """
---> 11 from linopy.remote.oetc import OetcCredentials, OetcHandler, OetcSettings
12 from linopy.remote.ssh import RemoteHandler
14 __all__ = [
15 "RemoteHandler",
16 "OetcHandler",
17 "OetcSettings",
18 "OetcCredentials",
19 ]
File ~/miniconda3/envs/pypsa-zambia-workshops/lib/python3.13/site-packages/linopy/remote/oetc.py:13
10 from enum import Enum
12 import requests
---> 13 from google.cloud import storage
14 from google.oauth2 import service_account
15 from requests import RequestException
File ~/miniconda3/envs/pypsa-zambia-workshops/lib/python3.13/site-packages/google/cloud/storage/__init__.py:35
1 # Copyright 2014 Google LLC
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License");
(...) 12 # See the License for the specific language governing permissions and
13 # limitations under the License.
15 """Shortcut methods for getting set up with Google Cloud Storage.
16
17 You'll typically use these to get started with the API:
(...) 31 machine).
32 """
---> 35 from pkg_resources import get_distribution
37 __version__ = get_distribution("google-cloud-storage").version
39 from google.cloud.storage.batch import Batch
ModuleNotFoundError: No module named 'pkg_resources'
First, we create a new Network object which serves as the overall container for all components.
n = pypsa.Network()
The second component we need are buses. Buses are the fundamental nodes of the network, to which all other components like loads, generators and transmission lines attach. They enforce energy conservation for all elements feeding in and out of it (i.e. Kirchhoff’s Current Law).
Components can be added to the network n using the n.add() function. It takes the component name as a first argument, the name of the component as a second argument and possibly further parameters as keyword arguments. Let’s use this function, to add buses for each country to our network:
n.add("Bus", "Copperbelt", y=-15.42, x=28.2, v_nom=400) # v_nom is nominal valtage [kV]
n.add("Bus", "Lusaka", y=-13.0, x=28.0, v_nom=400)
For each class of components, the data describing the components is stored as specific type DataFrame defined in pandas package which will be covered in Python session. You can check what is inside each component using n.{component}, such as
n.buses
| attribute | v_nom | type | x | y | carrier | unit | v_mag_pu_set | v_mag_pu_min | v_mag_pu_max | control | generator | sub_network |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Bus | ||||||||||||
| Copperbelt | 400.0 | 28.2 | -15.42 | AC | 1.0 | 0.0 | inf | PQ | ||||
| Lusaka | 400.0 | 28.0 | -13.00 | AC | 1.0 | 0.0 | inf | PQ |
You can look up on all the attributes available for buses here https://docs.pypsa.org/latest/user-guide/components/buses/, and similarly for all other components.
The n.add() function is very general. It lets you add any component to the network object n. For instance, in the next step we add Line component to connect both nodes:
n.add(
"Line",
"Lusaka-Copperbelt",
bus0="Lusaka",
bus1="Copperbelt",
s_nom=1_500, # transmission capacity [MW]
x=1,
r=1,
)
n.explore()
INFO:pypsa.plot:Components rendered on the map: Bus, Line.
INFO:pypsa.plot:Components omitted as they are missing or not selected: Generator, Link, Load, StorageUnit, Transformer.
Information about carriers must be added to distinguish between different energy sources. To make visualization nicer, we can also specify nice names and plotting colors.
n.add(
"Carrier",
["coal", "oil", "hydro"],
#co2_emissions=emissions,
nice_name=["Coal", "Oil", "Hydro"],
color=["dimgrey", "olive", "royalblue"],
)
n.add("Carrier", "AC", nice_name="Electricity", color="crimson")
Add generators#
Generator is component which can feed in power. Generators convert energy from their carrier to the carrier of the bus to which they attach with user-specified parameters for energy availability and transformation efficiency. They can be used to represent renewable generators with variable potential, dispatchable conventional power plants, or supply of grid electricity or an external import.
Availability of renewable generators is usually defined with p_max_pu which is the maximum value of the capacity factor.
n.add(
"Generator",
"Hydro Generation",
bus="Lusaka",
carrier="hydro",
p_nom=5000, # MW
p_max_pu=0.4, # hydro availability which depends on the weather year
marginal_cost=0, # default
)
For conventional generators, efficiencies and fuel costs can be specified:
fuel_cost = dict(
coal=8,
oil=48,
)
efficiency = dict(
coal=0.33,
oil=0.35,
)
n.add(
"Generator",
"Coal Generation",
bus="Copperbelt",
carrier="coal",
efficiency=efficiency.get("coal", 1),
p_nom=1750,
marginal_cost=fuel_cost.get("coal", 0) / efficiency.get("coal", 1),
)
n.add(
"Generator",
"Oil Generation",
bus="Copperbelt",
carrier="oil",
efficiency=efficiency.get("oil", 1),
p_nom=1200,
marginal_cost=fuel_cost.get("oil", 0) / efficiency.get("oil", 1),
)
As a result, the n.generators DataFrame looks like this:
n.generators
| attribute | bus | control | type | p_nom | p_nom_mod | p_nom_extendable | p_nom_min | p_nom_max | p_min_pu | p_max_pu | ... | min_up_time | min_down_time | up_time_before | down_time_before | ramp_limit_up | ramp_limit_down | ramp_limit_start_up | ramp_limit_shut_down | weight | p_nom_opt |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Generator | |||||||||||||||||||||
| Hydro Generation | Lusaka | PQ | 5000.0 | 0.0 | False | 0.0 | inf | 0.0 | 0.4 | ... | 0 | 0 | 1 | 0 | NaN | NaN | 1.0 | 1.0 | 1.0 | 0.0 | |
| Coal Generation | Copperbelt | PQ | 1750.0 | 0.0 | False | 0.0 | inf | 0.0 | 1.0 | ... | 0 | 0 | 1 | 0 | NaN | NaN | 1.0 | 1.0 | 1.0 | 0.0 | |
| Oil Generation | Copperbelt | PQ | 1200.0 | 0.0 | False | 0.0 | inf | 0.0 | 1.0 | ... | 0 | 0 | 1 | 0 | NaN | NaN | 1.0 | 1.0 | 1.0 | 0.0 |
3 rows × 34 columns
Add loads#
Next, we’re going to add the electricity demand. A positive value for p_set means consumption of power from the bus (in MW).
loads = {
"Lusaka": 700,
"Copperbelt": 3000,
}
n.add(
"Load",
"Lusaka electricity demand",
bus="Lusaka",
p_set=loads["Lusaka"],
carrier="AC",
)
n.add(
"Load",
"Copperbelt electricity demand",
bus="Copperbelt",
p_set=loads["Copperbelt"],
carrier="AC",
)
n_dry_year = n.copy()
n_wet_year = n.copy()
n.optimize(solver_name="highs", log_to_console=False)
WARNING:pypsa.consistency:The following generators have carriers which are not defined:
Index(['Hydro Generation', 'Coal Generation', 'Oil Generation'], dtype='object', name='Generator')
WARNING:pypsa.consistency:The following generators have carriers which are not defined:
Index(['Hydro Generation', 'Coal Generation', 'Oil Generation'], dtype='object', name='Generator')
INFO:linopy.model: Solve problem using Highs solver
INFO:linopy.model:Solver options:
- log_to_console: False
INFO:linopy.io: Writing time: 0.01s
INFO:linopy.constants: Optimization successful:
Status: ok
Termination condition: optimal
Solution: 4 primals, 10 duals
Objective: 4.12e+04
Solver model: available
Solver message: Optimal
INFO:pypsa.optimization.optimize:The shadow-prices of the constraints Generator-fix-p-lower, Generator-fix-p-upper, Line-fix-s-lower, Line-fix-s-upper were not assigned to the network.
Running HiGHS 1.11.0 (git hash: n/a): Copyright (c) 2025 HiGHS under MIT licence terms
('ok', 'optimal')
loads
{'Lusaka': 700, 'Copperbelt': 3000}
n.statistics()
| Optimal Capacity | Installed Capacity | Supply | Withdrawal | Energy Balance | Transmission | Capacity Factor | Curtailment | Capital Expenditure | Operational Expenditure | Revenue | Market Value | ||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Generator | coal | 1750.0 | 1750.0 | 1700.0 | 0.0 | 1700.0 | 0.0 | 0.971429 | 50.0 | 0.0 | 41212.12121 | 41212.12121 | 24.242424 |
| hydro | 5000.0 | 5000.0 | 2000.0 | 0.0 | 2000.0 | 0.0 | 0.400000 | 0.0 | 0.0 | 0.00000 | 48484.84848 | 24.242424 | |
| oil | 1200.0 | 1200.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.000000 | 1200.0 | 0.0 | 0.00000 | 0.00000 | 0.000000 | |
| Line | Electricity | 1500.0 | 1500.0 | 1300.0 | 1300.0 | 0.0 | 1300.0 | 0.866667 | 0.0 | 0.0 | 0.00000 | 0.00000 | NaN |
| Load | Electricity | 0.0 | 0.0 | 0.0 | 3700.0 | -3700.0 | 0.0 | NaN | 0.0 | 0.0 | 0.00000 | -89696.96970 | NaN |
Modify network#
Add a power transmission line with a specific transmission capacity s_nom [MW]
n.lines.loc["Lusaka-Copperbelt", "s_nom"] = 750
n.optimize()
WARNING:pypsa.consistency:The following generators have carriers which are not defined:
Index(['Hydro Generation', 'Coal Generation', 'Oil Generation'], dtype='object', name='Generator')
WARNING:pypsa.consistency:The following generators have carriers which are not defined:
Index(['Hydro Generation', 'Coal Generation', 'Oil Generation'], dtype='object', name='Generator')
INFO:linopy.model: Solve problem using Highs solver
INFO:linopy.io: Writing time: 0.01s
INFO:linopy.constants: Optimization successful:
Status: ok
Termination condition: optimal
Solution: 4 primals, 10 duals
Objective: 1.11e+05
Solver model: available
Solver message: Optimal
INFO:pypsa.optimization.optimize:The shadow-prices of the constraints Generator-fix-p-lower, Generator-fix-p-upper, Line-fix-s-lower, Line-fix-s-upper were not assigned to the network.
Running HiGHS 1.11.0 (git hash: n/a): Copyright (c) 2025 HiGHS under MIT licence terms
LP linopy-problem-6txvbqhq has 10 rows; 4 cols; 13 nonzeros
Coefficient ranges:
Matrix [1e+00, 1e+00]
Cost [2e+01, 1e+02]
Bound [0e+00, 0e+00]
RHS [7e+02, 3e+03]
Presolving model
1 rows, 2 cols, 2 nonzeros 0s
0 rows, 0 cols, 0 nonzeros 0s
Presolve : Reductions: rows 0(-10); columns 0(-4); elements 0(-13) - Reduced to empty
Solving the original LP from the solution after postsolve
Model name : linopy-problem-6txvbqhq
Model status : Optimal
Objective value : 1.1099567100e+05
P-D objective error : 1.3110285785e-16
HiGHS run time : 0.00
Writing the solution to /private/var/folders/qn/vpndfm21795ckkq89np1ckp40000gn/T/linopy-solve-15qbsnrh.sol
('ok', 'optimal')
n.statistics()
| Optimal Capacity | Installed Capacity | Supply | Withdrawal | Energy Balance | Transmission | Capacity Factor | Curtailment | Capital Expenditure | Operational Expenditure | Revenue | Market Value | ||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Generator | coal | 1750.0 | 1750.0 | 1750.0 | 0.0 | 1750.0 | 0.0 | 1.000000 | 0.0 | 0.0 | 42424.24242 | 240000.00000 | 137.142857 |
| hydro | 5000.0 | 5000.0 | 1450.0 | 0.0 | 1450.0 | 0.0 | 0.290000 | 550.0 | 0.0 | 0.00000 | 0.00000 | NaN | |
| oil | 1200.0 | 1200.0 | 500.0 | 0.0 | 500.0 | 0.0 | 0.416667 | 700.0 | 0.0 | 68571.42857 | 68571.42857 | 137.142857 | |
| Line | Electricity | 750.0 | 750.0 | 750.0 | 750.0 | 0.0 | 750.0 | 1.000000 | 0.0 | 0.0 | 0.00000 | 102857.14286 | 137.142857 |
| Load | Electricity | 0.0 | 0.0 | 0.0 | 3700.0 | -3700.0 | 0.0 | NaN | 0.0 | 0.0 | 0.00000 | -411428.57143 | NaN |
Hydrological scenarios#
n_dry_year.generators.loc["Hydro Generation", "p_max_pu"] = 0.3
n_wet_year.generators.loc["Hydro Generation", "p_max_pu"] = 0.6
n_dry_year.optimize(solver_name="highs", log_to_console=False)
WARNING:pypsa.consistency:The following generators have carriers which are not defined:
Index(['Hydro Generation', 'Coal Generation', 'Oil Generation'], dtype='object', name='Generator')
WARNING:pypsa.consistency:The following generators have carriers which are not defined:
Index(['Hydro Generation', 'Coal Generation', 'Oil Generation'], dtype='object', name='Generator')
INFO:linopy.model: Solve problem using Highs solver
INFO:linopy.model:Solver options:
- log_to_console: False
INFO:linopy.io: Writing time: 0.01s
INFO:linopy.constants: Optimization successful:
Status: ok
Termination condition: optimal
Solution: 4 primals, 10 duals
Objective: 1.04e+05
Solver model: available
Solver message: Optimal
INFO:pypsa.optimization.optimize:The shadow-prices of the constraints Generator-fix-p-lower, Generator-fix-p-upper, Line-fix-s-lower, Line-fix-s-upper were not assigned to the network.
Running HiGHS 1.11.0 (git hash: n/a): Copyright (c) 2025 HiGHS under MIT licence terms
('ok', 'optimal')
n_wet_year.optimize(solver_name="highs", log_to_console=False)
WARNING:pypsa.consistency:The following generators have carriers which are not defined:
Index(['Hydro Generation', 'Coal Generation', 'Oil Generation'], dtype='object', name='Generator')
WARNING:pypsa.consistency:The following generators have carriers which are not defined:
Index(['Hydro Generation', 'Coal Generation', 'Oil Generation'], dtype='object', name='Generator')
INFO:linopy.model: Solve problem using Highs solver
INFO:linopy.model:Solver options:
- log_to_console: False
INFO:linopy.io: Writing time: 0.01s
INFO:linopy.constants: Optimization successful:
Status: ok
Termination condition: optimal
Solution: 4 primals, 10 duals
Objective: 3.64e+04
Solver model: available
Solver message: Optimal
INFO:pypsa.optimization.optimize:The shadow-prices of the constraints Generator-fix-p-lower, Generator-fix-p-upper, Line-fix-s-lower, Line-fix-s-upper were not assigned to the network.
Running HiGHS 1.11.0 (git hash: n/a): Copyright (c) 2025 HiGHS under MIT licence terms
('ok', 'optimal')
n.statistics()
| Optimal Capacity | Installed Capacity | Supply | Withdrawal | Energy Balance | Transmission | Capacity Factor | Curtailment | Capital Expenditure | Operational Expenditure | Revenue | Market Value | ||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Generator | coal | 1750.0 | 1750.0 | 1750.0 | 0.0 | 1750.0 | 0.0 | 1.000000 | 0.0 | 0.0 | 42424.24242 | 240000.00000 | 137.142857 |
| hydro | 5000.0 | 5000.0 | 1450.0 | 0.0 | 1450.0 | 0.0 | 0.290000 | 550.0 | 0.0 | 0.00000 | 0.00000 | NaN | |
| oil | 1200.0 | 1200.0 | 500.0 | 0.0 | 500.0 | 0.0 | 0.416667 | 700.0 | 0.0 | 68571.42857 | 68571.42857 | 137.142857 | |
| Line | Electricity | 750.0 | 750.0 | 750.0 | 750.0 | 0.0 | 750.0 | 1.000000 | 0.0 | 0.0 | 0.00000 | 102857.14286 | 137.142857 |
| Load | Electricity | 0.0 | 0.0 | 0.0 | 3700.0 | -3700.0 | 0.0 | NaN | 0.0 | 0.0 | 0.00000 | -411428.57143 | NaN |
n_dry_year.statistics()
| Optimal Capacity | Installed Capacity | Supply | Withdrawal | Energy Balance | Transmission | Capacity Factor | Curtailment | Capital Expenditure | Operational Expenditure | Revenue | Market Value | ||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Generator | coal | 1750.0 | 1750.0 | 1750.0 | 0.0 | 1750.0 | 0.0 | 1.000000 | 0.0 | 0.0 | 42424.24242 | 240000.00000 | 137.142857 |
| hydro | 5000.0 | 5000.0 | 1500.0 | 0.0 | 1500.0 | 0.0 | 0.300000 | 0.0 | 0.0 | 0.00000 | 205714.28571 | 137.142857 | |
| oil | 1200.0 | 1200.0 | 450.0 | 0.0 | 450.0 | 0.0 | 0.375000 | 750.0 | 0.0 | 61714.28571 | 61714.28571 | 137.142857 | |
| Line | Electricity | 1500.0 | 1500.0 | 800.0 | 800.0 | 0.0 | 800.0 | 0.533333 | 0.0 | 0.0 | 0.00000 | 0.00000 | NaN |
| Load | Electricity | 0.0 | 0.0 | 0.0 | 3700.0 | -3700.0 | 0.0 | NaN | 0.0 | 0.0 | 0.00000 | -507428.57143 | NaN |
n_wet_year.statistics()
| Optimal Capacity | Installed Capacity | Supply | Withdrawal | Energy Balance | Transmission | Capacity Factor | Curtailment | Capital Expenditure | Operational Expenditure | Revenue | Market Value | ||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Generator | coal | 1750.0 | 1750.0 | 1500.0 | 0.0 | 1500.0 | 0.0 | 0.857143 | 250.0 | 0.0 | 36363.63636 | 36363.63636 | 24.242424 |
| hydro | 5000.0 | 5000.0 | 2200.0 | 0.0 | 2200.0 | 0.0 | 0.440000 | 800.0 | 0.0 | 0.00000 | 0.00000 | NaN | |
| oil | 1200.0 | 1200.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.000000 | 1200.0 | 0.0 | 0.00000 | 0.00000 | 0.000000 | |
| Line | Electricity | 1500.0 | 1500.0 | 1500.0 | 1500.0 | 0.0 | 1500.0 | 1.000000 | 0.0 | 0.0 | 0.00000 | 36363.63636 | 24.242424 |
| Load | Electricity | 0.0 | 0.0 | 0.0 | 3700.0 | -3700.0 | 0.0 | NaN | 0.0 | 0.0 | 0.00000 | -72727.27273 | NaN |
Comprehensive documentation is available for PyPSA
Example for modelling interconnection between South Africa and Mozambique
Key Dependencies#
pandasfor storing data about network components and time seriesnumpyandscipyfor linear algebra and sparse matrix calculationsmatplotlibandcartopyfor plotting on a mapnetworkxfor network calculationslinopyfor handling optimisation problems