fusionlab.plot.forecast.plot_forecast_by_step

fusionlab.plot.forecast.plot_forecast_by_step(df, value_prefixes=None, kind='dual', steps=None, step_names=None, spatial_cols=None, max_cols='auto', cmap='viridis', cbar='uniform', axis_off=False, show_grid=True, grid_props=None, figsize=None, savefig=None, save_fmts='.png', _logger=None, verbose=1)[source]

Plots forecast data, organizing subplots by forecast step.

This function creates a grid of plots to visualize forecast data from a long-format DataFrame. Each row in the grid corresponds to a unique forecast_step.

It robustly handles both spatial scatter plots (if spatial_cols are provided and found) and temporal line plots (as a fallback), making it versatile for different types of forecast data.

Parameters:
  • df (pd.DataFrame) – Input long-format DataFrame. Must contain a ‘forecast_step’ column and value columns (e.g., ‘subsidence_q50’).

  • value_prefixes (list of str, optional) – The base names of metrics to plot (e.g., ['subsidence']). If None, prefixes are auto-detected from column names. A separate figure is generated for each prefix.

  • kind ({'dual', 'pred_only'}, default 'dual') –

    Determines what to plot: - 'dual': Plots both actual values and predictions

    side-by-side for comparison.

    • 'pred_only': Plots only the predicted values.

  • steps (int or list of int, optional) – A specific forecast step or list of steps to visualize. If None, all unique steps found in the DataFrame are plotted.

  • step_names (dict or list, optional) –

    Custom labels for the forecast steps in plot titles. - If a dict, maps step numbers to names (e.g., {1: 'Year 1'}). - If a list, maps step index to names (e.g., ['Y1', 'Y2'],

    where index 0 corresponds to step 1).

  • spatial_cols (tuple of str, optional) – Tuple of column names for spatial coordinates, e.g., ('coord_x', 'coord_y'). If provided and found, spatial scatter plots are created. If None or columns are not found, the function falls back to temporal line plots.

  • max_cols (int or 'auto', default 'auto') – Controls the number of subplots per row. If 'auto', it’s determined by the number of metrics (e.g., actual + quantiles) being plotted for each prefix.

  • cmap (str, default 'viridis') – The Matplotlib colormap for spatial plots.

  • cbar ({'uniform', 'individual'}, default 'uniform') – Controls color bar scaling for spatial plots. - 'uniform': All subplots share a single color scale. - 'individual': Each subplot has its own color scale.

  • axis_off (bool, default False) – If True, turns off plot axes, ticks, and labels.

  • show_grid (bool, default True) – If True and axis_off is False, displays a grid on the subplots.

  • grid_props (dict, optional) – Properties for the grid, e.g., {'linestyle': '--'}.

  • figsize (tuple of (float, float), optional) – The size of the figure for each value_prefix. If None, the size is automatically calculated based on the layout.

  • savefig (str, optional) – Path to save the figure(s). The prefix name and ‘_by_step’ will be appended (e.g., ‘my_plot_subsidence_by_step.png’).

  • save_fmts (str or list of str, default '.png') – Format(s) to save the figure, e.g., ['.png', '.pdf'].

  • verbose (int, default 1) – Controls the verbosity of logging messages.

  • _logger (Logger | Callable[[str], None] | None)

Returns:

This function displays and/or saves Matplotlib figures and does not return any value.

Return type:

None

See also

forecast_view

A related function that plots by year/time instead of by step index.

Notes

  • The function expects a long-format DataFrame where each row is a unique combination of a sample and a forecast step.

  • If spatial_cols are not found, temporal line plots are generated by plotting values against the DataFrame’s index. This is most meaningful when the DataFrame is sorted by a relevant variable (e.g., a spatial coordinate) for each step.

Examples

>>> import pandas as pd
>>> # from fusionlab.plot.forecast import plot_forecast_by_step
>>> data = {
...     'sample_idx':      list(range(4)) * 2,
...     'forecast_step':   [1] * 4 + [2] * 4,
...     'coord_x':         np.random.rand(8),
...     'coord_y':         np.random.rand(8),
...     'subsidence_q50':  np.random.randn(8),
...     'subsidence_actual': np.random.randn(8),
... }
>>> df_step_example = pd.DataFrame(data)
>>> # plot_forecast_by_step(
... #     df=df_step_example,
... #     value_prefixes=['subsidence'],
... #     spatial_cols=('coord_x', 'coord_y'),
... #     step_names={1: 'Year 1 Forecast', 2: 'Year 2 Forecast'},
... #     kind='dual'
... # )