Skip to content

flixopt.plotting

Comprehensive visualization toolkit for flixopt optimization results and data analysis.

This module provides a unified plotting interface supporting both Plotly (interactive) and Matplotlib (static) backends for visualizing energy system optimization results. It offers specialized plotting functions for time series, heatmaps, network diagrams, and statistical analyses commonly needed in energy system modeling.

Key Features

Dual Backend Support: Seamless switching between Plotly and Matplotlib Energy System Focus: Specialized plots for power flows, storage states, emissions Color Management: Intelligent color processing and palette management Export Capabilities: High-quality export for reports and publications Integration Ready: Designed for use with CalculationResults and standalone analysis

Main Plot Types
  • Time Series: Flow rates, power profiles, storage states over time
  • Heatmaps: High-resolution temporal data visualization with customizable aggregation
  • Network Diagrams: System topology with flow visualization
  • Statistical Plots: Distribution analysis, correlation studies, performance metrics
  • Comparative Analysis: Multi-scenario and sensitivity study visualizations

The module integrates seamlessly with flixopt's result classes while remaining accessible for standalone data visualization tasks.

Attributes

ColorType module-attribute

ColorType = str | list[str] | dict[str, str]

Flexible color specification type supporting multiple input formats for visualization.

Color specifications can take several forms to accommodate different use cases:

Named Colormaps (str): - Standard colormaps: 'viridis', 'plasma', 'cividis', 'tab10', 'Set1' - Energy-focused: 'portland' (custom flixopt colormap for energy systems) - Backend-specific maps available in Plotly and Matplotlib

Color Lists (list[str]): - Explicit color sequences: ['red', 'blue', 'green', 'orange'] - HEX codes: ['#FF0000', '#0000FF', '#00FF00', '#FFA500'] - Mixed formats: ['red', '#0000FF', 'green', 'orange']

Label-to-Color Mapping (dict[str, str]): - Explicit associations: {'Wind': 'skyblue', 'Solar': 'gold', 'Gas': 'brown'} - Ensures consistent colors across different plots and datasets - Ideal for energy system components with semantic meaning

Examples:

# Named colormap
colors = 'viridis'  # Automatic color generation

# Explicit color list
colors = ['red', 'blue', 'green', '#FFD700']

# Component-specific mapping
colors = {
    'Wind_Turbine': 'skyblue',
    'Solar_Panel': 'gold',
    'Natural_Gas': 'brown',
    'Battery': 'green',
    'Electric_Load': 'darkred'
}
Color Format Support
  • Named Colors: 'red', 'blue', 'forestgreen', 'darkorange'
  • HEX Codes: '#FF0000', '#0000FF', '#228B22', '#FF8C00'
  • RGB Tuples: (255, 0, 0), (0, 0, 255) [Matplotlib only]
  • RGBA: 'rgba(255,0,0,0.8)' [Plotly only]
References
  • HTML Color Names: https://htmlcolorcodes.com/color-names/
  • Matplotlib Colormaps: https://matplotlib.org/stable/tutorials/colors/colormaps.html
  • Plotly Built-in Colorscales: https://plotly.com/python/builtin-colorscales/

PlottingEngine module-attribute

PlottingEngine = Literal['plotly', 'matplotlib']

Identifier for the plotting engine to use.

Classes

ColorProcessor

ColorProcessor(engine: PlottingEngine = 'plotly', default_colormap: str = 'viridis')

Intelligent color management system for consistent multi-backend visualization.

This class provides unified color processing across Plotly and Matplotlib backends, ensuring consistent visual appearance regardless of the plotting engine used. It handles color palette generation, named colormap translation, and intelligent color cycling for complex datasets with many categories.

Key Features

Backend Agnostic: Automatic color format conversion between engines Palette Management: Support for named colormaps, custom palettes, and color lists Intelligent Cycling: Smart color assignment for datasets with many categories Fallback Handling: Graceful degradation when requested colormaps are unavailable Energy System Colors: Built-in palettes optimized for energy system visualization

Color Input Types
  • Named Colormaps: 'viridis', 'plasma', 'portland', 'tab10', etc.
  • Color Lists: ['red', 'blue', 'green'] or ['#FF0000', '#0000FF', '#00FF00']
  • Label Dictionaries: {'Generator': 'red', 'Storage': 'blue', 'Load': 'green'}

Examples:

Basic color processing:

# Initialize for Plotly backend
processor = ColorProcessor(engine='plotly', default_colormap='viridis')

# Process different color specifications
colors = processor.process_colors('plasma', ['Gen1', 'Gen2', 'Storage'])
colors = processor.process_colors(['red', 'blue', 'green'], ['A', 'B', 'C'])
colors = processor.process_colors({'Wind': 'skyblue', 'Solar': 'gold'}, ['Wind', 'Solar', 'Gas'])

# Switch to Matplotlib
processor = ColorProcessor(engine='matplotlib')
mpl_colors = processor.process_colors('tab10', component_labels)

Energy system visualization:

# Specialized energy system palette
energy_colors = {
    'Natural_Gas': '#8B4513',  # Brown
    'Electricity': '#FFD700',  # Gold
    'Heat': '#FF4500',  # Red-orange
    'Cooling': '#87CEEB',  # Sky blue
    'Hydrogen': '#E6E6FA',  # Lavender
    'Battery': '#32CD32',  # Lime green
}

processor = ColorProcessor('plotly')
flow_colors = processor.process_colors(energy_colors, flow_labels)

Parameters:

Name Type Description Default
engine PlottingEngine

Plotting backend ('plotly' or 'matplotlib'). Determines output color format.

'plotly'
default_colormap str

Fallback colormap when requested palettes are unavailable. Common options: 'viridis', 'plasma', 'tab10', 'portland'.

'viridis'

Initialize the color processor with specified backend and defaults.

Functions

process_colors
process_colors(colors: ColorType, labels: list[str], return_mapping: bool = False) -> list[Any] | dict[str, Any]

Process colors for the specified labels.

Parameters:

Name Type Description Default
colors ColorType

Color specification (colormap name, list of colors, or label-to-color mapping)

required
labels list[str]

list of data labels that need colors assigned

required
return_mapping bool

If True, returns a dictionary mapping labels to colors; if False, returns a list of colors in the same order as labels

False

Returns:

Type Description
list[Any] | dict[str, Any]

Either a list of colors or a dictionary mapping labels to colors

Functions

with_plotly

with_plotly(data: DataFrame, style: Literal['stacked_bar', 'line', 'area', 'grouped_bar'] = 'stacked_bar', colors: ColorType = 'viridis', title: str = '', ylabel: str = '', xlabel: str = 'Time in h', fig: Figure | None = None) -> go.Figure

Plot a DataFrame with Plotly, using either stacked bars or stepped lines.

Parameters:

Name Type Description Default
data DataFrame

A DataFrame containing the data to plot, where the index represents time (e.g., hours), and each column represents a separate data series.

required
style Literal['stacked_bar', 'line', 'area', 'grouped_bar']

The plotting style. Use 'stacked_bar' for stacked bar charts, 'line' for stepped lines, or 'area' for stacked area charts.

'stacked_bar'
colors ColorType

Color specification, can be: - A string with a colorscale name (e.g., 'viridis', 'plasma') - A list of color strings (e.g., ['#ff0000', '#00ff00']) - A dictionary mapping column names to colors (e.g., {'Column1': '#ff0000'})

'viridis'
title str

The title of the plot.

''
ylabel str

The label for the y-axis.

''
xlabel str

The label for the x-axis.

'Time in h'
fig Figure | None

A Plotly figure object to plot on. If not provided, a new figure will be created.

None

Returns:

Type Description
Figure

A Plotly figure object containing the generated plot.

with_matplotlib

with_matplotlib(data: DataFrame, style: Literal['stacked_bar', 'line'] = 'stacked_bar', colors: ColorType = 'viridis', title: str = '', ylabel: str = '', xlabel: str = 'Time in h', figsize: tuple[int, int] = (12, 6), fig: Figure | None = None, ax: Axes | None = None) -> tuple[plt.Figure, plt.Axes]

Plot a DataFrame with Matplotlib using stacked bars or stepped lines.

Parameters:

Name Type Description Default
data DataFrame

A DataFrame containing the data to plot. The index should represent time (e.g., hours), and each column represents a separate data series.

required
style Literal['stacked_bar', 'line']

Plotting style. Use 'stacked_bar' for stacked bar charts or 'line' for stepped lines.

'stacked_bar'
colors ColorType

Color specification, can be: - A string with a colormap name (e.g., 'viridis', 'plasma') - A list of color strings (e.g., ['#ff0000', '#00ff00']) - A dictionary mapping column names to colors (e.g., {'Column1': '#ff0000'})

'viridis'
title str

The title of the plot.

''
ylabel str

The ylabel of the plot.

''
xlabel str

The xlabel of the plot.

'Time in h'
figsize tuple[int, int]

Specify the size of the figure

(12, 6)
fig Figure | None

A Matplotlib figure object to plot on. If not provided, a new figure will be created.

None
ax Axes | None

A Matplotlib axes object to plot on. If not provided, a new axes will be created.

None

Returns:

Type Description
tuple[Figure, Axes]

A tuple containing the Matplotlib figure and axes objects used for the plot.

Notes
  • If style is 'stacked_bar', bars are stacked for both positive and negative values. Negative values are stacked separately without extra labels in the legend.
  • If style is 'line', stepped lines are drawn for each data series.

heat_map_matplotlib

heat_map_matplotlib(data: DataFrame, color_map: str = 'viridis', title: str = '', xlabel: str = 'Period', ylabel: str = 'Step', figsize: tuple[float, float] = (12, 6)) -> tuple[plt.Figure, plt.Axes]

Plots a DataFrame as a heatmap using Matplotlib. The columns of the DataFrame will be displayed on the x-axis, the index will be displayed on the y-axis, and the values will represent the 'heat' intensity in the plot.

Parameters:

Name Type Description Default
data DataFrame

A DataFrame containing the data to be visualized. The index will be used for the y-axis, and columns will be used for the x-axis. The values in the DataFrame will be represented as colors in the heatmap.

required
color_map str

The colormap to use for the heatmap. Default is 'viridis'. Matplotlib supports various colormaps like 'plasma', 'inferno', 'cividis', etc.

'viridis'
title str

The title of the plot.

''
xlabel str

The label for the x-axis.

'Period'
ylabel str

The label for the y-axis.

'Step'
figsize tuple[float, float]

The size of the figure to create. Default is (12, 6), which results in a width of 12 inches and a height of 6 inches.

(12, 6)

Returns:

Type Description
Figure

A tuple containing the Matplotlib Figure and Axes objects. The Figure contains the overall plot, while the Axes is the area

Axes

where the heatmap is drawn. These can be used for further customization or saving the plot to a file.

Notes
  • The y-axis is flipped so that the first row of the DataFrame is displayed at the top of the plot.
  • The color scale is normalized based on the minimum and maximum values in the DataFrame.
  • The x-axis labels (periods) are placed at the top of the plot.
  • The colorbar is added horizontally at the bottom of the plot, with a label.

heat_map_plotly

heat_map_plotly(data: DataFrame, color_map: str = 'viridis', title: str = '', xlabel: str = 'Period', ylabel: str = 'Step', categorical_labels: bool = True) -> go.Figure

Plots a DataFrame as a heatmap using Plotly. The columns of the DataFrame will be mapped to the x-axis, and the index will be displayed on the y-axis. The values in the DataFrame will represent the 'heat' in the plot.

Parameters:

Name Type Description Default
data DataFrame

A DataFrame with the data to be visualized. The index will be used for the y-axis, and columns will be used for the x-axis. The values in the DataFrame will be represented as colors in the heatmap.

required
color_map str

The color scale to use for the heatmap. Default is 'viridis'. Plotly supports various color scales like 'Cividis', 'Inferno', etc.

'viridis'
title str

The title of the heatmap. Default is an empty string.

''
xlabel str

The label for the x-axis. Default is 'Period'.

'Period'
ylabel str

The label for the y-axis. Default is 'Step'.

'Step'
categorical_labels bool

If True, the x and y axes are treated as categorical data (i.e., the index and columns will not be interpreted as continuous data). Default is True. If False, the axes are treated as continuous, which may be useful for time series or numeric data.

True

Returns:

Type Description
Figure

A Plotly figure object containing the heatmap. This can be further customized and saved

Figure

or displayed using fig.show().

Notes

The color bar is automatically scaled to the minimum and maximum values in the data. The y-axis is reversed to display the first row at the top.

reshape_to_2d

reshape_to_2d(data_1d: ndarray, nr_of_steps_per_column: int) -> np.ndarray

Reshapes a 1D numpy array into a 2D array suitable for plotting as a colormap.

The reshaped array will have the number of rows corresponding to the steps per column (e.g., 24 hours per day) and columns representing time periods (e.g., days or months).

Parameters:

Name Type Description Default
data_1d ndarray

A 1D numpy array with the data to reshape.

required
nr_of_steps_per_column int

The number of steps (rows) per column in the resulting 2D array. For example, this could be 24 (for hours) or 31 (for days in a month).

required

Returns:

Type Description
ndarray

The reshaped 2D array. Each internal array corresponds to one column, with the specified number of steps.

ndarray

Each column might represents a time period (e.g., day, month, etc.).

heat_map_data_from_df

heat_map_data_from_df(df: DataFrame, periods: Literal['YS', 'MS', 'W', 'D', 'h', '15min', 'min'], steps_per_period: Literal['W', 'D', 'h', '15min', 'min'], fill: Literal['ffill', 'bfill'] | None = None) -> pd.DataFrame

Reshapes a DataFrame with a DateTime index into a 2D array for heatmap plotting, based on a specified sample rate. Only specific combinations of periods and steps_per_period are supported; invalid combinations raise an assertion.

Parameters:

Name Type Description Default
df DataFrame

A DataFrame with a DateTime index containing the data to reshape.

required
periods Literal['YS', 'MS', 'W', 'D', 'h', '15min', 'min']

The time interval of each period (columns of the heatmap), such as 'YS' (year start), 'W' (weekly), 'D' (daily), 'h' (hourly) etc.

required
steps_per_period Literal['W', 'D', 'h', '15min', 'min']

The time interval within each period (rows in the heatmap), such as 'YS' (year start), 'W' (weekly), 'D' (daily), 'h' (hourly) etc.

required
fill Literal['ffill', 'bfill'] | None

Method to fill missing values: 'ffill' for forward fill or 'bfill' for backward fill.

None

Returns:

Type Description
DataFrame

A DataFrame suitable for heatmap plotting, with rows representing steps within each period

DataFrame

and columns representing each period.

plot_network

plot_network(node_infos: dict, edge_infos: dict, path: str | Path | None = None, controls: bool | list[Literal['nodes', 'edges', 'layout', 'interaction', 'manipulation', 'physics', 'selection', 'renderer']] = True, show: bool = False) -> pyvis.network.Network | None

Visualizes the network structure of a FlowSystem using PyVis, using info-dictionaries.

Parameters:

Name Type Description Default
path str | Path | None

Path to save the HTML visualization. False: Visualization is created but not saved. str or Path: Specifies file path (default: 'results/network.html').

None
controls bool | list[Literal['nodes', 'edges', 'layout', 'interaction', 'manipulation', 'physics', 'selection', 'renderer']]

UI controls to add to the visualization. True: Enables all available controls. list: Specify controls, e.g., ['nodes', 'layout']. Options: 'nodes', 'edges', 'layout', 'interaction', 'manipulation', 'physics', 'selection', 'renderer'. You can play with these and generate a Dictionary from it that can be applied to the network returned by this function. network.set_options() https://pyvis.readthedocs.io/en/latest/tutorial.html

True
show bool

Whether to open the visualization in the web browser. The calculation must be saved to show it. If no path is given, it defaults to 'network.html'.

False

Returns: The Network instance representing the visualization, or None if pyvis is not installed.

Notes: - This function requires pyvis. If not installed, the function prints a warning and returns None. - Nodes are styled based on type (e.g., circles for buses, boxes for components) and annotated with node information.

pie_with_plotly

pie_with_plotly(data: DataFrame, colors: ColorType = 'viridis', title: str = '', legend_title: str = '', hole: float = 0.0, fig: Figure | None = None) -> go.Figure

Create a pie chart with Plotly to visualize the proportion of values in a DataFrame.

Parameters:

Name Type Description Default
data DataFrame

A DataFrame containing the data to plot. If multiple rows exist, they will be summed unless a specific index value is passed.

required
colors ColorType

Color specification, can be: - A string with a colorscale name (e.g., 'viridis', 'plasma') - A list of color strings (e.g., ['#ff0000', '#00ff00']) - A dictionary mapping column names to colors (e.g., {'Column1': '#ff0000'})

'viridis'
title str

The title of the plot.

''
legend_title str

The title for the legend.

''
hole float

Size of the hole in the center for creating a donut chart (0.0 to 1.0).

0.0
fig Figure | None

A Plotly figure object to plot on. If not provided, a new figure will be created.

None

Returns:

Type Description
Figure

A Plotly figure object containing the generated pie chart.

Notes
  • Negative values are not appropriate for pie charts and will be converted to absolute values with a warning.
  • If the data contains very small values (less than 1% of the total), they can be grouped into an "Other" category for better readability.
  • By default, the sum of all columns is used for the pie chart. For time series data, consider preprocessing.

pie_with_matplotlib

pie_with_matplotlib(data: DataFrame, colors: ColorType = 'viridis', title: str = '', legend_title: str = 'Categories', hole: float = 0.0, figsize: tuple[int, int] = (10, 8), fig: Figure | None = None, ax: Axes | None = None) -> tuple[plt.Figure, plt.Axes]

Create a pie chart with Matplotlib to visualize the proportion of values in a DataFrame.

Parameters:

Name Type Description Default
data DataFrame

A DataFrame containing the data to plot. If multiple rows exist, they will be summed unless a specific index value is passed.

required
colors ColorType

Color specification, can be: - A string with a colormap name (e.g., 'viridis', 'plasma') - A list of color strings (e.g., ['#ff0000', '#00ff00']) - A dictionary mapping column names to colors (e.g., {'Column1': '#ff0000'})

'viridis'
title str

The title of the plot.

''
legend_title str

The title for the legend.

'Categories'
hole float

Size of the hole in the center for creating a donut chart (0.0 to 1.0).

0.0
figsize tuple[int, int]

The size of the figure (width, height) in inches.

(10, 8)
fig Figure | None

A Matplotlib figure object to plot on. If not provided, a new figure will be created.

None
ax Axes | None

A Matplotlib axes object to plot on. If not provided, a new axes will be created.

None

Returns:

Type Description
tuple[Figure, Axes]

A tuple containing the Matplotlib figure and axes objects used for the plot.

Notes
  • Negative values are not appropriate for pie charts and will be converted to absolute values with a warning.
  • If the data contains very small values (less than 1% of the total), they can be grouped into an "Other" category for better readability.
  • By default, the sum of all columns is used for the pie chart. For time series data, consider preprocessing.

dual_pie_with_plotly

dual_pie_with_plotly(data_left: Series, data_right: Series, colors: ColorType = 'viridis', title: str = '', subtitles: tuple[str, str] = ('Left Chart', 'Right Chart'), legend_title: str = '', hole: float = 0.2, lower_percentage_group: float = 5.0, hover_template: str = '%{label}: %{value} (%{percent})', text_info: str = 'percent+label', text_position: str = 'inside') -> go.Figure

Create two pie charts side by side with Plotly, with consistent coloring across both charts.

Parameters:

Name Type Description Default
data_left Series

Series for the left pie chart.

required
data_right Series

Series for the right pie chart.

required
colors ColorType

Color specification, can be: - A string with a colorscale name (e.g., 'viridis', 'plasma') - A list of color strings (e.g., ['#ff0000', '#00ff00']) - A dictionary mapping category names to colors (e.g., {'Category1': '#ff0000'})

'viridis'
title str

The main title of the plot.

''
subtitles tuple[str, str]

Tuple containing the subtitles for (left, right) charts.

('Left Chart', 'Right Chart')
legend_title str

The title for the legend.

''
hole float

Size of the hole in the center for creating donut charts (0.0 to 1.0).

0.2
lower_percentage_group float

Group segments whose cumulative share is below this percentage (0–100) into "Other".

5.0
hover_template str

Template for hover text. Use %{label}, %{value}, %{percent}.

'%{label}: %{value} (%{percent})'
text_info str

What to show on pie segments: 'label', 'percent', 'value', 'label+percent', 'label+value', 'percent+value', 'label+percent+value', or 'none'.

'percent+label'
text_position str

Position of text: 'inside', 'outside', 'auto', or 'none'.

'inside'

Returns:

Type Description
Figure

A Plotly figure object containing the generated dual pie chart.

dual_pie_with_matplotlib

dual_pie_with_matplotlib(data_left: Series, data_right: Series, colors: ColorType = 'viridis', title: str = '', subtitles: tuple[str, str] = ('Left Chart', 'Right Chart'), legend_title: str = '', hole: float = 0.2, lower_percentage_group: float = 5.0, figsize: tuple[int, int] = (14, 7), fig: Figure | None = None, axes: list[Axes] | None = None) -> tuple[plt.Figure, list[plt.Axes]]

Create two pie charts side by side with Matplotlib, with consistent coloring across both charts. Leverages the existing pie_with_matplotlib function.

Parameters:

Name Type Description Default
data_left Series

Series for the left pie chart.

required
data_right Series

Series for the right pie chart.

required
colors ColorType

Color specification, can be: - A string with a colormap name (e.g., 'viridis', 'plasma') - A list of color strings (e.g., ['#ff0000', '#00ff00']) - A dictionary mapping category names to colors (e.g., {'Category1': '#ff0000'})

'viridis'
title str

The main title of the plot.

''
subtitles tuple[str, str]

Tuple containing the subtitles for (left, right) charts.

('Left Chart', 'Right Chart')
legend_title str

The title for the legend.

''
hole float

Size of the hole in the center for creating donut charts (0.0 to 1.0).

0.2
lower_percentage_group float

Whether to group small segments (below percentage) into an "Other" category.

5.0
figsize tuple[int, int]

The size of the figure (width, height) in inches.

(14, 7)
fig Figure | None

A Matplotlib figure object to plot on. If not provided, a new figure will be created.

None
axes list[Axes] | None

A list of Matplotlib axes objects to plot on. If not provided, new axes will be created.

None

Returns:

Type Description
tuple[Figure, list[Axes]]

A tuple containing the Matplotlib figure and list of axes objects used for the plot.

export_figure

export_figure(figure_like: Figure | tuple[Figure, Axes], default_path: Path, default_filetype: str | None = None, user_path: Path | None = None, show: bool = True, save: bool = False) -> go.Figure | tuple[plt.Figure, plt.Axes]

Export a figure to a file and or show it.

Parameters:

Name Type Description Default
figure_like Figure | tuple[Figure, Axes]

The figure to export. Can be a Plotly figure or a tuple of Matplotlib figure and axes.

required
default_path Path

The default file path if no user filename is provided.

required
default_filetype str | None

The default filetype if the path doesnt end with a filetype.

None
user_path Path | None

An optional user-specified file path.

None
show bool

Whether to display the figure (default: True).

True
save bool

Whether to save the figure (default: False).

False

Raises:

Type Description
ValueError

If no default filetype is provided and the path doesn't specify a filetype.

TypeError

If the figure type is not supported.