Forecast Visualization Utilities

fusionlab-learn provides a powerful suite of plotting functions specifically designed to visualize time series forecast results. These utilities are built on pandas and matplotlib, offering a flexible and intuitive way to inspect model predictions, compare them against actual values, and analyze performance across different dimensions like time, space, or forecast horizon.

This guide covers the main functions for generating temporal line plots, spatial scatter plots, and structured grid visualizations of your forecast data.


General-Purpose Forecasting Plots (plot_forecasts)

API Reference:

plot_forecasts()

This is the primary and most versatile plotting function. It is designed to handle a wide variety of forecasting visualization tasks from a single, standardized long-format DataFrame (typically generated by format_predictions_to_dataframe()).

Key Capabilities:

  • Temporal & Spatial Modes: Can generate both time series line plots (kind='temporal') for individual samples and spatial scatter plots (kind='spatial') for specific forecast steps.

  • Probabilistic Visualization: Natively handles quantile forecasts, plotting the median prediction as a line and the outer quantiles as a shaded uncertainty interval.

  • Actuals Comparison: Can automatically overlay true actual values for direct comparison with model predictions.

  • Scaler Integration: Can automatically apply the inverse_transform method of a provided scikit-learn-like scaler to display results in their original physical units.

Example 1: Temporal Quantile Forecast

This example shows how to plot the forecast for a few individual samples over the entire forecast horizon, complete with uncertainty bounds.

 1import pandas as pd
 2import numpy as np
 3from fusionlab.plot.forecast import plot_forecasts
 4from fusionlab.nn.utils import format_predictions_to_dataframe
 5
 6# 1. Assume we have model predictions and true values
 7B, H, O, Q_len = 10, 7, 1, 3
 8preds_quant = np.random.rand(B, H, Q_len) * 2
 9y_true_seq = preds_quant[:, :, 1, np.newaxis] + np.random.randn(B, H, O) * 0.2
10quantiles_list = [0.1, 0.5, 0.9]
11
12# 2. Format data into the required long-format DataFrame
13df_quant = format_predictions_to_dataframe(
14    predictions=preds_quant, y_true_sequences=y_true_seq,
15    target_name="subsidence", quantiles=quantiles_list,
16    forecast_horizon=H, output_dim=O
17)
18
19# 3. Generate the plot for the first 2 samples
20plot_forecasts(
21    df_quant,
22    target_name="subsidence",
23    quantiles=quantiles_list,
24    kind="temporal",
25    sample_ids="first_n", # Plot the first N samples
26    num_samples=2,
27    max_cols=2 # Arrange plots in 2 columns
28)

Expected Output:

Temporal Quantile Forecast Plot

A figure with two subplots, each showing the forecast for a single sample. The plots include the true actual values (dashed line), the median prediction (solid line), and the shaded uncertainty interval.

Example 2: Spatial Forecast Snapshot

This example shows how to visualize the spatial distribution of a forecast at a single step into the future. This requires the DataFrame to have columns containing spatial coordinates.

 1# Add spatial coordinates to our previous DataFrame
 2df_quant['longitude'] = np.random.rand(len(df_quant)) * 50
 3df_quant['latitude'] = np.random.rand(len(df_quant)) * 50
 4
 5# 3. Generate the spatial plot for the 3rd forecast step
 6plot_forecasts(
 7    df_quant,
 8    target_name="subsidence",
 9    quantiles=quantiles_list,
10    kind="spatial",
11    horizon_steps=3, # Visualize the 3rd step of the horizon
12    spatial_cols=['longitude', 'latitude'],
13    cbar='uniform' # Use a uniform color bar for all plots
14)

Expected Output:

Spatial Forecast Plot

A single spatial scatter plot for the 3rd forecast step. The color of each point represents the predicted median subsidence value at that location.


Visualizing by Forecast Step (plot_forecast_by_step)

API Reference:

plot_forecast_by_step()

This function is specifically designed to analyze how a model’s forecast evolves across its prediction horizon. It creates a grid of plots where each row represents a forecast step (e.g., 1-step-ahead, 2-steps-ahead, etc.). This is extremely useful for diagnosing error propagation and understanding how far into the future the model remains reliable.

 1from fusionlab.plot.forecast import plot_forecast_by_step
 2
 3# Use the same DataFrame from the previous example
 4plot_forecast_by_step(
 5    df=df_quant,
 6    value_prefixes=['subsidence'],
 7    spatial_cols=('longitude', 'latitude'),
 8    # Create side-by-side plots for actual vs. predicted
 9    kind='dual',
10    # Provide custom names for the steps
11    step_names={
12        1: "1-Step Ahead", 3: "3-Steps Ahead", 5: "5-Steps Ahead"
13    },
14    # Only plot steps 1, 3, and 5
15    steps=[1, 3, 5]
16)

Expected Output:

Forecast by Step Plot

A grid of plots with three rows, one for each forecast step (1, 3, and 5). Each row contains multiple columns showing the spatial distribution of the actual values and the predicted quantiles for that specific step.


Yearly/Periodic Spatial Views (forecast_view)

API Reference:

forecast_view()

This function is a powerful tool for creating a grid of spatial forecast plots organized by a specific time period, such as a year. It is ideal for comparing how the spatial distribution of a forecast evolves across different evaluation periods (e.g., comparing the predicted subsidence map for 2023 vs. 2024).

The function is designed to work with a “wide-format” DataFrame where columns represent different years and metrics. It includes an internal helper to automatically pivot data from a long format if necessary, making it user-friendly.

Key Capabilities:

  • Period-Based Grid: Automatically creates rows in the output figure for each unique period (e.g., year) specified in view_years.

  • Metric-Based Columns: Arranges plots column-wise to compare different metrics (e.g., “Actuals”, “p50 Forecast”, “p90 Forecast”) side-by-side for the same period.

  • Uniform Color Scaling: Can enforce a single, uniform color scale (via cbar='uniform') across all subplots, making it easy to visually compare magnitudes between different years and metrics.

  • Automatic Data Handling: Intelligently detects value prefixes (like ‘subsidence’ or ‘gwl’) and quantile levels from the DataFrame columns.

Usage Example

This example demonstrates how to use forecast_view to compare the spatial forecast for two different years, showing the actual values alongside two predicted quantiles.

 1import pandas as pd
 2import numpy as np
 3from fusionlab.plot.forecast import forecast_view
 4
 5# 1. Create a sample long-format DataFrame with a 'year' column
 6n_points_per_year = 50
 7data = {
 8    'coord_x': np.random.rand(n_points_per_year * 2),
 9    'coord_y': np.random.rand(n_points_per_year * 2),
10    'year': [2023] * n_points_per_year + [2024] * n_points_per_year,
11    'subsidence_actual': np.random.randn(n_points_per_year * 2),
12    'subsidence_q10': np.random.randn(n_points_per_year * 2) * 0.8,
13    'subsidence_q90': np.random.randn(n_points_per_year * 2) * 1.2,
14}
15df_yearly = pd.DataFrame(data)
16
17# 2. add the `sample_idx` column (one id per row here; adjust as needed)
18df_yearly["sample_idx"] = np.arange(len(df_yearly))
19# ── or, if you have repeated measurements per point:
20# df_yearly["sample_idx"] = (df_yearly["coord_x"].round(3).astype(str)
21#                            + "_" +
22#                            df_yearly["coord_y"].round(3).astype(str))
23
24# 2. Generate the plot
25forecast_view(
26    forecast_df=df_yearly,
27    dt_col="year",
28    value_prefixes=['subsidence'],
29    spatial_cols=('coord_x', 'coord_y'),
30    kind='dual', # Show actuals and predictions
31    # Specify which years and quantiles to visualize
32    view_years=[2023, 2024],
33    view_quantiles=[0.1, 0.9],
34    cmap ='seismic',
35    s=100,
36    cbar='uniform'
37)

Expected Output:

Yearly Forecast View Plot

A grid of plots with two rows (for years 2023 and 2024). Each row shows the actual spatial distribution for that year, followed by the predicted spatial distributions for the 10th and 90th quantiles.


Legacy Comparison Plot (visualize_forecasts)

API Reference:

visualize_forecasts()

The visualize_forecasts function is an earlier utility for creating a grid of scatter plots that compare actual values from a test_data DataFrame with predicted values from a forecast_df.

Note

For most use cases, the newer and more flexible plot_forecasts() and forecast_view() functions are recommended. visualize_forecasts is maintained for specific workflows where forecast and test data are stored in separate DataFrames.

Its primary design is to create a plot grid where each specified evaluation period gets its own pair of subplots: one for the actual data and one for the predicted data, facilitating direct visual comparison.

 1from fusionlab.plot.forecast import visualize_forecasts
 2
 3# 1. Create separate forecast and test DataFrames
 4forecast_data = pd.DataFrame({
 5    'longitude': np.random.rand(50),
 6    'latitude': np.random.rand(50),
 7    'subsidence_q50': np.random.randn(50),
 8    'date': pd.to_datetime(['2023-06-01'] * 50)
 9})
10test_data_actuals = pd.DataFrame({
11    'longitude': np.random.rand(50),
12    'latitude': np.random.rand(50),
13    'subsidence': np.random.randn(50),
14    'date': pd.to_datetime(['2023-06-01'] * 50)
15})
16
17# 2. Generate the comparison plot
18visualize_forecasts(
19    forecast_df=forecast_data,
20    test_data=test_data_actuals,
21    dt_col="date",
22    tname="subsidence",
23    eval_periods=['2023'], # Must match the year in the data
24    mode="quantile",
25    kind="spatial",
26    x="longitude",
27    y="latitude",
28    max_cols=1,
29    s=100,
30)

Expected Output:

Legacy Forecast Comparison Plot

A figure with two subplots stacked vertically. The top plot shows the spatial distribution of the actual subsidence values from the test_data DataFrame for the year 2023. The bottom plot shows the predicted median (q50) subsidence values from the forecast_df.