Visualizing Forecasts with K-Diagram¶
fusionlab-learn focuses on generating robust time series
forecasts. To gain deeper insights into these forecasts, especially
regarding uncertainty and model behavior over time or across
different segments, the k-diagram
library offers a suite of specialized polar visualizations.
This guide demonstrates how to use k-diagram (accessed via
fusionlab.kdiagram if installed as an extra) with the outputs
generated by fusionlab-learn models. Predictions are typically
formatted into a pandas DataFrame using utilities like
format_predictions_to_dataframe().
Prerequisites:
Ensure fusionlab-learn is installed with the kdiagram extra,
which will also install the k-diagram package and matplotlib:
pip install fusionlab-learn[k-diagram]
If you have fusionlab-learn already and only need k-diagram:
pip install k-diagram matplotlib
Preparing Forecast Data for K-Diagram¶
Most k-diagram plotting functions expect a pandas DataFrame.
After training a fusionlab-learn model (e.g.,
XTFT or
TemporalFusionTransformer) and generating
predictions, you would typically use
format_predictions_to_dataframe() to
structure your forecasts.
Let’s assume you have a forecast_df from this utility. For point forecasts, it might have columns like sample_idx, forecast_step, my_target_actual, my_target_pred. For quantile forecasts, it might have my_target_q10, my_target_q50, my_target_q90, in addition to actuals.
The following examples will simulate such DataFrames and then use fusionlab.kdiagram for visualization.
Example 1: Actual vs. Predicted Plot¶
The plot_actual_vs_predicted() function
provides a polar scatter plot comparing actual values against model
predictions. This can help identify systematic biases or how prediction
errors are distributed.
Scenario:
Imagine you have point forecasts from a fusionlab-learn model.
1import pandas as pd
2import numpy as np
3import matplotlib.pyplot as plt
4import os
5
6# Import kdiagram via fusionlab's proxy
7import fusionlab.kdiagram as fkd
8# If kdiagram was installed separately, you could also do:
9# import kdiagram as kd
10
11# Ensure output directory for images exists relative to where script is run
12# For Sphinx, paths in .. figure:: are relative to the .rst file
13output_image_dir = "docs/source/images" # Adjust if script runs from project root
14os.makedirs(output_image_dir, exist_ok=True)
15
16# --- Simulate a forecast_df from fusionlab ---
17np.random.seed(42)
18num_forecast_points = 150
19actual_values = 50 + 10 * np.sin(
20 np.linspace(0, 5 * np.pi, num_forecast_points)
21 ) + np.random.normal(0, 5, num_forecast_points)
22predicted_values = actual_values * 0.9 + \
23 np.random.normal(0, 4, num_forecast_points) + 5
24
25forecast_eval_df = pd.DataFrame({
26 'sales_actual': actual_values,
27 'sales_pred': predicted_values,
28 'time_index': np.arange(num_forecast_points)
29})
30print("Sample of DataFrame for Actual vs. Predicted plot:")
31print(forecast_eval_df.head())
32
33# --- Plotting with fusionlab.kdiagram ---
34# Note: kdiagram functions are accessed via fusionlab.kdiagram
35# if the proxy is set up correctly and k-diagram is installed.
36try:
37 kd.plot.plot_actual_vs_predicted(
38 df=forecast_eval_df,
39 actual_col='sales_actual',
40 pred_col='sales_pred',
41 title='FusionLab & K-Diagram: Actual vs. Predicted Sales',
42 line=False, # Use dots for this example
43 r_label="Sales Value",
44 actual_props={
45 'marker': '.', 's': 50, 'alpha': 0.7,
46 'color': '#007acc' # Blue
47 },
48 pred_props={
49 'marker': '+', 's': 60, 'alpha': 0.8,
50 'color': '#e85e00' # Valid orange hex
51 },
52 savefig=os.path.join(
53 output_image_dir,
54 "fusionlab_kdiag_actual_vs_pred.png"
55 )
56 )
57 #plt.close()
58 print(
59 f"Plot saved to "
60 f"{output_image_dir}/fusionlab_kdiag_actual_vs_pred.png"
61 )
62except ImportError as e:
63 print(f"K-Diagram not available through fusionlab.kdiagram: {e}")
64except Exception as e:
65 print(f"An error occurred during plotting: {e}")
Expected Output & Plot 1:
Sample of DataFrame for Actual vs. Predicted plot:
sales_actual sales_pred time_index
0 52.483571 53.237185 0
1 50.360953 51.710650 1
2 55.331307 52.078077 2
3 60.725365 60.581843 3
4 52.922266 53.802329 4
...
Plot saved to docs/source/images/fusionlab_kdiag_actual_vs_pred.png
Polar plot comparing actual sales to FusionLab model predictions, visualized using k-diagram via fusionlab.kdiagram.¶
Example 2: Coverage Diagnostic Plot¶
For quantile forecasts,
plot_coverage_diagnostic()
visualizes whether the actual values fall within the predicted
uncertainty intervals.
Scenario:
You have quantile forecasts (e.g., q10, q50, q90) from a fusionlab-learn model.
1import pandas as pd
2import numpy as np
3import matplotlib.pyplot as plt
4import os
5import fusionlab.kdiagram as fkd
6
7# output_image_dir defined in previous cell
8
9# --- Simulate a forecast_df with quantiles ---
10np.random.seed(88)
11num_forecast_points = 200
12actual_values_q = np.random.normal(loc=30, scale=5, size=num_forecast_points)
13q10_values = actual_values_q - np.random.uniform(2, 6, num_forecast_points)
14q50_values = actual_values_q + np.random.normal(0, 1, num_forecast_points)
15q90_values = actual_values_q + np.random.uniform(2, 6, num_forecast_points)
16actual_values_q[::20] = q90_values[::20] + 2
17actual_values_q[::25] = q10_values[::25] - 2
18
19forecast_quant_df = pd.DataFrame({
20 'demand_actual': actual_values_q,
21 'demand_q10': q10_values,
22 'demand_q50': q50_values,
23 'demand_q90': q90_values
24})
25print("\nSample of DataFrame for Coverage Diagnostic plot:")
26print(forecast_quant_df.head())
27
28# --- Plotting with fusionlab.kdiagram ---
29try:
30 fkd.plot.plot_coverage_diagnostic(
31 df=forecast_quant_df,
32 actual_col='demand_actual',
33 q_cols=['demand_q10', 'demand_q90'],
34 title='FusionLab & K-Diagram: Interval Coverage (Q10-Q90)',
35 as_bars=True, # Use bars for this example
36 fill_gradient=True,
37 coverage_line_color='purple', # Changed color
38 bar_props={'alpha': 0.7},
39 verbose=0,
40 savefig=os.path.join(output_image_dir, "fusionlab_kdiag_coverage.png")
41 )
42 plt.close()
43 print(f"Plot saved to {output_image_dir}/fusionlab_kdiag_coverage.png")
44except ImportError as e:
45 print(f"K-Diagram not available through fusionlab.kdiagram: {e}")
46except Exception as e:
47 print(f"An error occurred during plotting: {e}")
Expected Output & Plot 2:
Sample of DataFrame for Coverage Diagnostic plot:
demand_actual demand_q10 demand_q50 demand_q90
0 33.003098 29.332539 32.480096 35.169899
1 26.928811 23.406621 27.742191 28.759837
...
Plot saved to docs/source/images/fusionlab_kdiag_coverage.png
Point-wise coverage diagnostic for FusionLab quantile forecasts, visualized using k-diagram via fusionlab.kdiagram.¶
Example 3: Model Drift Plot¶
plot_model_drift() helps visualize
if prediction interval characteristics change across different forecast
horizons or segments.
Scenario: Data is in a wide format where each horizon’s quantiles are columns.
1import pandas as pd
2import numpy as np
3import matplotlib.pyplot as plt
4import os
5import fusionlab.kdiagram as fkd
6
7# output_image_dir defined previously
8
9np.random.seed(0)
10horizons_labels = ['H_Step1', 'H_Step2', 'H_Step3', 'H_Step4']
11num_samples_drift = 50
12df_drift = pd.DataFrame()
13q10_cols_drift, q90_cols_drift = [], []
14
15for i, hor_label in enumerate(horizons_labels):
16 q10_colname = f'pred_{hor_label}_q10'
17 q90_colname = f'pred_{hor_label}_q90'
18 q10_cols_drift.append(q10_colname)
19 q90_cols_drift.append(q90_colname)
20 q10_vals = np.random.rand(num_samples_drift) * 5 + i * 0.7
21 q90_vals = q10_vals + np.random.rand(num_samples_drift) * 2.5 + 1.5 + i * 1.0
22 df_drift[q10_colname] = q10_vals
23 df_drift[q90_colname] = q90_vals
24
25print("\nSample of DataFrame for Model Drift plot:")
26print(df_drift.head(2))
27
28try:
29 fkd.plot.plot_model_drift(
30 df=df_drift,
31 q10_cols=q10_cols_drift,
32 q90_cols=q90_cols_drift,
33 horizons=horizons_labels,
34 acov='semi_circle', # Changed angular coverage
35 title='FusionLab & K-Diagram: Interval Drift',
36 cmap='plasma', # Changed colormap
37 savefig=os.path.join(output_image_dir, "fusionlab_kdiag_model_drift.png")
38 )
39 plt.close()
40 print(f"Plot saved to {output_image_dir}/fusionlab_kdiag_model_drift.png")
41except ImportError as e:
42 print(f"K-Diagram not available through fusionlab.kdiagram: {e}")
43except Exception as e:
44 print(f"An error occurred during plotting: {e}")
Expected Output & Plot 3:
Sample of DataFrame for Model Drift plot:
pred_H_Step1_q10 pred_H_Step1_q90 pred_H_Step2_q10 pred_H_Step2_q90
0 2.744068 6.988482 3.907212 9.010952
1 3.575947 6.010909 4.975008 8.061101
Plot saved to docs/source/images/fusionlab_kdiag_model_drift.png
Visualization of prediction interval drift across forecast horizons, using k-diagram via fusionlab.kdiagram.¶
Example 4: Prediction Velocity Plot¶
plot_velocity() visualizes the rate
and direction of change in predictions across consecutive horizons.
Scenario: Data is wide, with median forecasts for different horizons as columns.
1import pandas as pd
2import numpy as np
3import matplotlib.pyplot as plt
4import os
5import fusionlab.kdiagram as fkd
6
7# output_image_dir defined previously
8
9np.random.seed(123)
10num_points_vel = 100
11horizon_labels_vel = ['Forecast_H1', 'Forecast_H2', 'Forecast_H3', 'Forecast_H4']
12df_velocity = pd.DataFrame({'sample_id': range(num_points_vel)})
13base_value_vel = np.random.rand(num_points_vel) * 20
14trend_vel = np.linspace(0, 3, num_points_vel)
15
16for i, hor_label in enumerate(horizon_labels_vel):
17 noise_vel = np.random.randn(num_points_vel) * 0.8
18 df_velocity[hor_label] = base_value_vel + trend_vel * (i + 1) + noise_vel
19print("\nSample of DataFrame for Velocity plot:")
20print(df_velocity.head(2))
21
22try:
23 fkd.plot.plot_velocity(
24 df=df_velocity,
25 q50_cols=horizon_labels_vel, # List of median forecast columns
26 title='FusionLab & K-Diagram: Prediction Velocity',
27 use_abs_color=True, # Color by magnitude
28 normalize=True,
29 cmap='magma', # Changed colormap
30 cbar=True,
31 s=35, # Marker size
32 savefig=os.path.join(output_image_dir, "fusionlab_kdiag_velocity.png")
33 )
34 plt.close()
35 print(f"Plot saved to {output_image_dir}/fusionlab_kdiag_velocity.png")
36except ImportError as e:
37 print(f"K-Diagram not available through fusionlab.kdiagram: {e}")
38except Exception as e:
39 print(f"An error occurred during plotting: {e}")
Expected Output & Plot 4:
Sample of DataFrame for Velocity plot:
sample_id Forecast_H1 Forecast_H2 Forecast_H3 Forecast_H4
0 0 0.592269 1.467803 2.614264 2.931038
1 1 8.900599 9.887309 9.900808 9.969413
Plot saved to docs/source/images/fusionlab_kdiag_velocity.png
Visualization of prediction velocity using k-diagram via fusionlab.kdiagram.¶
Example 5: Taylor Diagram for Model Comparison¶
plot_taylor_diagram_in()
summarizes model performance against reference values.
Scenario:
Comparing point predictions from two fusionlab-learn models.
1import numpy as np
2import matplotlib.pyplot as plt
3import os
4# Import directly from fusionlab.kdiagram.plot.evaluation
5from fusionlab.kdiagram.plot import evaluation as fl_kde
6
7# output_image_dir defined previously
8
9np.random.seed(42)
10reference_actuals = np.random.normal(10, 2, 100)
11preds_model_A = reference_actuals * 0.85 + np.random.normal(0, 0.8, 100)
12preds_model_B = reference_actuals * 0.6 + np.random.normal(0, 1.5, 100) + 1
13model_names = ['FusionLab_Model_A', 'FusionLab_Model_B']
14
15try:
16 fl_kde.plot_taylor_diagram_in(
17 preds_model_A, preds_model_B,
18 reference=reference_actuals,
19 names=model_names,
20 acov='half_circle', # Changed angular coverage
21 zero_location='N',
22 direction=1,
23 fig_size=(7.5, 7.5), # Slightly different size
24 cmap='RdYlBu', # Different colormap
25 radial_strategy='rmse', # Color by RMSE
26 title='FusionLab & K-Diagram: Taylor Diagram Comparison',
27 savefig=os.path.join(output_image_dir, "fusionlab_kdiag_taylor.png")
28 )
29 plt.close()
30 print(f"\nPlot saved to {output_image_dir}/fusionlab_kdiag_taylor.png")
31except ImportError as e:
32 print(f"K-Diagram (or its submodule) not available through fusionlab.kdiagram: {e}")
33except Exception as e:
34 print(f"An error occurred during plotting: {e}")
Expected Output & Plot 5:
Plot saved to docs/source/images/fusionlab_kdiag_taylor.png
Taylor diagram comparing FusionLab models, visualized using k-diagram via fusionlab.kdiagram.¶
This guide provides a starting point for using k-diagram with
fusionlab-learn. Explore the k-diagram documentation for more
customization options and advanced features to further enhance your
forecast evaluation and communication.