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  ¶
  Flexible color specification type supporting multiple input formats for visualization.
Color specifications can take several forms to accommodate different use cases:
Named colorscales (str): - Standard colorscales: 'turbo', 'plasma', 'cividis', 'tab10', 'Set1' - Energy-focused: 'portland' (custom flixopt colorscale 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 colorscale
colors = 'turbo'  # 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 colorscales: https://matplotlib.org/stable/tutorials/colors/colorscales.html
 - Plotly Built-in Colorscales: https://plotly.com/python/builtin-colorscales/
 
 PlottingEngine  module-attribute  ¶
  Identifier for the plotting engine to use.
Classes¶
Functions¶
with_plotly ¶
with_plotly(data: Dataset | DataFrame | Series, mode: Literal['stacked_bar', 'line', 'area', 'grouped_bar'] = 'stacked_bar', colors: ColorType | None = None, title: str = '', ylabel: str = '', xlabel: str = '', facet_by: str | list[str] | None = None, animate_by: str | None = None, facet_cols: int | None = None, shared_yaxes: bool = True, shared_xaxes: bool = True, **px_kwargs: Any) -> go.Figure
Plot data with Plotly using facets (subplots) and/or animation for multidimensional data.
Uses Plotly Express for convenient faceting and animation with automatic styling.
Parameters:
| Name | Type | Description | Default | 
|---|---|---|---|
 data  |   Dataset | DataFrame | Series  |    An xarray Dataset, pandas DataFrame, or pandas Series to plot.  |  required | 
 mode  |   Literal['stacked_bar', 'line', 'area', 'grouped_bar']  |    The plotting mode. Use 'stacked_bar' for stacked bar charts, 'line' for lines, 'area' for stacked area charts, or 'grouped_bar' for grouped bar charts.  |   'stacked_bar'  |  
 colors  |   ColorType | None  |    Color specification (colorscale, list, or dict mapping labels to colors).  |   None  |  
 title  |   str  |    The main title of the plot.  |   ''  |  
 ylabel  |   str  |    The label for the y-axis.  |   ''  |  
 xlabel  |   str  |    The label for the x-axis.  |   ''  |  
 facet_by  |   str | list[str] | None  |    Dimension(s) to create facets for. Creates a subplot grid. Can be a single dimension name or list of dimensions (max 2 for facet_row and facet_col). If the dimension doesn't exist in the data, it will be silently ignored.  |   None  |  
 animate_by  |   str | None  |    Dimension to animate over. Creates animation frames. If the dimension doesn't exist in the data, it will be silently ignored.  |   None  |  
 facet_cols  |   int | None  |    Number of columns in the facet grid (used when facet_by is single dimension).  |   None  |  
 shared_yaxes  |   bool  |    Whether subplots share y-axes.  |   True  |  
 shared_xaxes  |   bool  |    Whether subplots share x-axes.  |   True  |  
 **px_kwargs  |   Any  |    Additional keyword arguments passed to the underlying Plotly Express function (px.bar, px.line, px.area). These override default arguments if provided. Examples: range_x=[0, 100], range_y=[0, 50], category_orders={...}, line_shape='linear'  |   {}  |  
Returns:
| Type | Description | 
|---|---|
 Figure  |    A Plotly figure object containing the faceted/animated plot. You can further customize  |  
 Figure  |    the returned figure using Plotly's methods (e.g., fig.update_traces(), fig.update_layout()).  |  
Examples:
Simple plot:
Facet by scenario:
Animate by period:
Facet and animate:
Customize with Plotly Express kwargs:
Further customize the returned figure:
with_matplotlib ¶
with_matplotlib(data: Dataset | DataFrame | Series, mode: Literal['stacked_bar', 'line'] = 'stacked_bar', colors: ColorType | None = None, title: str = '', ylabel: str = '', xlabel: str = 'Time in h', figsize: tuple[int, int] = (12, 6), plot_kwargs: dict[str, Any] | None = None) -> tuple[plt.Figure, plt.Axes]
Plot data with Matplotlib using stacked bars or stepped lines.
Parameters:
| Name | Type | Description | Default | 
|---|---|---|---|
 data  |   Dataset | DataFrame | Series  |    An xarray Dataset, pandas DataFrame, or pandas Series to plot. After conversion to DataFrame, the index represents time and each column represents a separate data series (variables).  |  required | 
 mode  |   Literal['stacked_bar', 'line']  |    Plotting mode. Use 'stacked_bar' for stacked bar charts or 'line' for stepped lines.  |   'stacked_bar'  |  
 colors  |   ColorType | None  |    Color specification. Can be: - A colorscale name (e.g., 'turbo', 'plasma') - A list of color strings (e.g., ['#ff0000', '#00ff00']) - A dict mapping column names to colors (e.g., {'Column1': '#ff0000'})  |   None  |  
 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 (width, height) in inches.  |   (12, 6)  |  
 plot_kwargs  |   dict[str, Any] | None  |    Optional dict of parameters to pass to ax.bar() or ax.step() plotting calls. Use this to customize plot properties (e.g., linewidth, alpha, edgecolor).  |   None  |  
Returns:
| Type | Description | 
|---|---|
 tuple[Figure, Axes]  |    A tuple containing the Matplotlib figure and axes objects used for the plot.  |  
Notes
- If 
modeis 'stacked_bar', bars are stacked for both positive and negative values. Negative values are stacked separately without extra labels in the legend. - If 
modeis 'line', stepped lines are drawn for each data series. 
reshape_data_for_heatmap ¶
reshape_data_for_heatmap(data: DataArray, reshape_time: tuple[Literal['YS', 'MS', 'W', 'D', 'h', '15min', 'min'], Literal['W', 'D', 'h', '15min', 'min']] | Literal['auto'] | None = 'auto', facet_by: str | list[str] | None = None, animate_by: str | None = None, fill: Literal['ffill', 'bfill'] | None = 'ffill') -> xr.DataArray
Reshape data for heatmap visualization, handling time dimension intelligently.
This function decides whether to reshape the 'time' dimension based on the reshape_time parameter: - 'auto': Automatically reshapes if only 'time' dimension would remain for heatmap - Tuple: Explicitly reshapes time with specified parameters - None: No reshaping (returns data as-is)
All non-time dimensions are preserved during reshaping.
Parameters:
| Name | Type | Description | Default | 
|---|---|---|---|
 data  |   DataArray  |    DataArray to reshape for heatmap visualization.  |  required | 
 reshape_time  |   tuple[Literal['YS', 'MS', 'W', 'D', 'h', '15min', 'min'], Literal['W', 'D', 'h', '15min', 'min']] | Literal['auto'] | None  |    Reshaping configuration: - 'auto' (default): Auto-reshape if needed based on facet_by/animate_by - Tuple (timeframes, timesteps_per_frame): Explicit time reshaping - None: No reshaping  |   'auto'  |  
 facet_by  |   str | list[str] | None  |    Dimension(s) used for faceting (used in 'auto' decision).  |   None  |  
 animate_by  |   str | None  |    Dimension used for animation (used in 'auto' decision).  |   None  |  
 fill  |   Literal['ffill', 'bfill'] | None  |    Method to fill missing values: 'ffill' or 'bfill'. Default is 'ffill'.  |   'ffill'  |  
Returns:
| Type | Description | 
|---|---|
 DataArray  |    Reshaped DataArray. If time reshaping is applied, 'time' dimension is replaced  |  
 DataArray  |    by 'timestep' and 'timeframe'. All other dimensions are preserved.  |  
Examples:
Auto-reshaping:
# Will auto-reshape because only 'time' remains after faceting/animation
data = reshape_data_for_heatmap(data, reshape_time='auto', facet_by='scenario', animate_by='period')
Explicit reshaping:
# Explicitly reshape to daily pattern
data = reshape_data_for_heatmap(data, reshape_time=('D', 'h'))
No reshaping:
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.   |   None  |  
 controls  |   bool | list[Literal['nodes', 'edges', 'layout', 'interaction', 'manipulation', 'physics', 'selection', 'renderer']]  |    UI controls to add to the visualization.   |   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.
preprocess_data_for_pie ¶
preprocess_data_for_pie(data: Dataset | DataFrame | Series, lower_percentage_threshold: float = 5.0) -> pd.Series
Preprocess data for pie chart display.
Groups items that are individually below the threshold percentage into an "Other" category. Converts various input types to a pandas Series for uniform handling.
Parameters:
| Name | Type | Description | Default | 
|---|---|---|---|
 data  |   Dataset | DataFrame | Series  |    Input data (xarray Dataset, DataFrame, or Series)  |  required | 
 lower_percentage_threshold  |   float  |    Percentage threshold - items below this are grouped into "Other"  |   5.0  |  
Returns:
| Type | Description | 
|---|---|
 Series  |    Processed pandas Series with small items grouped into "Other"  |  
dual_pie_with_plotly ¶
dual_pie_with_plotly(data_left: Dataset | DataFrame | Series, data_right: Dataset | DataFrame | Series, colors: ColorType | None = None, title: str = '', subtitles: tuple[str, str] = ('Left Chart', 'Right Chart'), legend_title: str = '', hole: float = 0.2, lower_percentage_group: float = 5.0, text_info: str = 'percent+label', text_position: str = 'inside', hover_template: str = '%{label}: %{value} (%{percent})') -> go.Figure
Create two pie charts side by side with Plotly.
Parameters:
| Name | Type | Description | Default | 
|---|---|---|---|
 data_left  |   Dataset | DataFrame | Series  |    Data for the left pie chart. Variables are summed across all dimensions.  |  required | 
 data_right  |   Dataset | DataFrame | Series  |    Data for the right pie chart. Variables are summed across all dimensions.  |  required | 
 colors  |   ColorType | None  |    Color specification (colorscale name, list of colors, or dict mapping)  |   None  |  
 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  |    Plotly Figure object  |  
dual_pie_with_matplotlib ¶
dual_pie_with_matplotlib(data_left: Dataset | DataFrame | Series, data_right: Dataset | DataFrame | Series, colors: ColorType | None = None, 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)) -> tuple[plt.Figure, list[plt.Axes]]
Create two pie charts side by side with Matplotlib.
Parameters:
| Name | Type | Description | Default | 
|---|---|---|---|
 data_left  |   Dataset | DataFrame | Series  |    Data for the left pie chart.  |  required | 
 data_right  |   Dataset | DataFrame | Series  |    Data for the right pie chart.  |  required | 
 colors  |   ColorType | None  |    Color specification (colorscale name, list of colors, or dict mapping)  |   None  |  
 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)  |  
Returns:
| Type | Description | 
|---|---|
 tuple[Figure, list[Axes]]  |    Tuple of (Figure, list of Axes)  |  
heatmap_with_plotly ¶
heatmap_with_plotly(data: DataArray, colors: ColorType | None = None, title: str = '', facet_by: str | list[str] | None = None, animate_by: str | None = None, facet_cols: int | None = None, reshape_time: tuple[Literal['YS', 'MS', 'W', 'D', 'h', '15min', 'min'], Literal['W', 'D', 'h', '15min', 'min']] | Literal['auto'] | None = 'auto', fill: Literal['ffill', 'bfill'] | None = 'ffill', **imshow_kwargs: Any) -> go.Figure
Plot a heatmap visualization using Plotly's imshow with faceting and animation support.
This function creates heatmap visualizations from xarray DataArrays, supporting multi-dimensional data through faceting (subplots) and animation. It automatically handles dimension reduction and data reshaping for optimal heatmap display.
Automatic Time Reshaping
If only the 'time' dimension remains after faceting/animation (making the data 1D), the function automatically reshapes time into a 2D format using default values (timeframes='D', timesteps_per_frame='h'). This creates a daily pattern heatmap showing hours vs days.
Parameters:
| Name | Type | Description | Default | 
|---|---|---|---|
 data  |   DataArray  |    An xarray DataArray containing the data to visualize. Should have at least 2 dimensions, or a 'time' dimension that can be reshaped into 2D.  |  required | 
 colors  |   ColorType | None  |    Color specification (colorscale name, list, or dict). Common options: 'turbo', 'plasma', 'RdBu', 'portland'.  |   None  |  
 title  |   str  |    The main title of the heatmap.  |   ''  |  
 facet_by  |   str | list[str] | None  |    Dimension to create facets for. Creates a subplot grid. Can be a single dimension name or list (only first dimension used). Note: px.imshow only supports single-dimension faceting. If the dimension doesn't exist in the data, it will be silently ignored.  |   None  |  
 animate_by  |   str | None  |    Dimension to animate over. Creates animation frames. If the dimension doesn't exist in the data, it will be silently ignored.  |   None  |  
 facet_cols  |   int | None  |    Number of columns in the facet grid (used with facet_by).  |   None  |  
 reshape_time  |   tuple[Literal['YS', 'MS', 'W', 'D', 'h', '15min', 'min'], Literal['W', 'D', 'h', '15min', 'min']] | Literal['auto'] | None  |    Time reshaping configuration: - 'auto' (default): Automatically applies ('D', 'h') if only 'time' dimension remains - Tuple like ('D', 'h'): Explicit time reshaping (days vs hours) - None: Disable time reshaping (will error if only 1D time data)  |   'auto'  |  
 fill  |   Literal['ffill', 'bfill'] | None  |    Method to fill missing values when reshaping time: 'ffill' or 'bfill'. Default is 'ffill'.  |   'ffill'  |  
 **imshow_kwargs  |   Any  |    Additional keyword arguments to pass to plotly.express.imshow. Common options include: - aspect: 'auto', 'equal', or a number for aspect ratio - zmin, zmax: Minimum and maximum values for color scale - labels: Dict to customize axis labels  |   {}  |  
Returns:
| Type | Description | 
|---|---|
 Figure  |    A Plotly figure object containing the heatmap visualization.  |  
Examples:
Simple heatmap:
Facet by scenario:
Animate by period:
Automatic time reshaping (when only time dimension remains):
# Data with dims ['time', 'scenario', 'period']
# After faceting and animation, only 'time' remains -> auto-reshapes to (timestep, timeframe)
fig = heatmap_with_plotly(data_array, facet_by='scenario', animate_by='period')
Explicit time reshaping:
heatmap_with_matplotlib ¶
heatmap_with_matplotlib(data: DataArray, colors: ColorType | None = None, title: str = '', figsize: tuple[float, float] = (12, 6), reshape_time: tuple[Literal['YS', 'MS', 'W', 'D', 'h', '15min', 'min'], Literal['W', 'D', 'h', '15min', 'min']] | Literal['auto'] | None = 'auto', fill: Literal['ffill', 'bfill'] | None = 'ffill', vmin: float | None = None, vmax: float | None = None, imshow_kwargs: dict[str, Any] | None = None, cbar_kwargs: dict[str, Any] | None = None, **kwargs: Any) -> tuple[plt.Figure, plt.Axes]
Plot a heatmap visualization using Matplotlib's imshow.
This function creates a basic 2D heatmap from an xarray DataArray using matplotlib's imshow function. For multi-dimensional data, only the first two dimensions are used.
Parameters:
| Name | Type | Description | Default | 
|---|---|---|---|
 data  |   DataArray  |    An xarray DataArray containing the data to visualize. Should have at least 2 dimensions. If more than 2 dimensions exist, additional dimensions will be reduced by taking the first slice.  |  required | 
 colors  |   ColorType | None  |    Color specification. Should be a colorscale name (e.g., 'turbo', 'RdBu').  |   None  |  
 title  |   str  |    The title of the heatmap.  |   ''  |  
 figsize  |   tuple[float, float]  |    The size of the figure (width, height) in inches.  |   (12, 6)  |  
 reshape_time  |   tuple[Literal['YS', 'MS', 'W', 'D', 'h', '15min', 'min'], Literal['W', 'D', 'h', '15min', 'min']] | Literal['auto'] | None  |    Time reshaping configuration: - 'auto' (default): Automatically applies ('D', 'h') if only 'time' dimension - Tuple like ('D', 'h'): Explicit time reshaping (days vs hours) - None: Disable time reshaping  |   'auto'  |  
 fill  |   Literal['ffill', 'bfill'] | None  |    Method to fill missing values when reshaping time: 'ffill' or 'bfill'. Default is 'ffill'.  |   'ffill'  |  
 vmin  |   float | None  |    Minimum value for color scale. If None, uses data minimum.  |   None  |  
 vmax  |   float | None  |    Maximum value for color scale. If None, uses data maximum.  |   None  |  
 imshow_kwargs  |   dict[str, Any] | None  |    Optional dict of parameters to pass to ax.imshow(). Use this to customize image properties (e.g., interpolation, aspect).  |   None  |  
 cbar_kwargs  |   dict[str, Any] | None  |    Optional dict of parameters to pass to plt.colorbar(). Use this to customize colorbar properties (e.g., orientation, label).  |   None  |  
 **kwargs  |   Any  |    Additional keyword arguments passed to ax.imshow(). Common options include: - interpolation: 'nearest', 'bilinear', 'bicubic', etc. - alpha: Transparency level (0-1) - extent: [left, right, bottom, top] for axis limits  |   {}  |  
Returns:
| Type | Description | 
|---|---|
 tuple[Figure, Axes]  |    A tuple containing the Matplotlib figure and axes objects used for the plot.  |  
Notes
- Matplotlib backend doesn't support faceting or animation. Use plotly engine for those features.
 - The y-axis is automatically inverted to display data with origin at top-left.
 - A colorbar is added to show the value scale.
 
Examples:
fig, ax = heatmap_with_matplotlib(data_array, colors='RdBu', title='Temperature')
plt.savefig('heatmap.png')
Time reshaping:
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 | None = None, save: bool = False, dpi: int | None = None) -> 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 | None  |    Whether to display the figure. If None, uses CONFIG.Plotting.default_show (default: None).  |   None  |  
 save  |   bool  |    Whether to save the figure (default: False).  |   False  |  
 dpi  |   int | None  |    DPI (dots per inch) for saving Matplotlib figures. If None, uses CONFIG.Plotting.default_dpi.  |   None  |  
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.  |