| name | plotting |
| description | Use this skill any time a forecast chart, visualization, or figure is created. This includes: plotting single forecasts, grid comparisons, counterfactual scenario fans, backtest result charts, or any matplotlib figure using Migas-1.5 outputs. Trigger whenever the user mentions plotting, charting, visualizing, or saving forecast figures. |
Plotting Migas-1.5 Forecasts
Always call apply_migas_style() once before any plotting to get consistent,
release-quality styling.
Setup
from migaseval.plotting_utils import (
COLORS,
apply_migas_style,
plot_forecast_single,
plot_forecast_grid,
_draw_forecast_region,
)
apply_migas_style()
Color Palette
Use the COLORS dict for consistent styling across all plots:
| Key | Hex | Use |
|---|
"historical" | #5D6D7E | Context window (slate gray) |
"ground_truth" | #1B2631 | Actual future values (charcoal) |
"Migas-1.5" | #F28C28 | Migas-1.5 forecast (vibrant teal/orange — hero color) |
"Chronos-2" | #4A90D9 | Chronos baseline (steel blue) |
"forecast_region" | #FDF6EC | Background shading for forecast zone |
"forecast_vline" | #ABB2B9 | Vertical divider at forecast boundary |
For counterfactual scenarios, the notebooks use:
- Bullish:
#2EAD6D (green)
- Bearish:
#C0392B (red)
- Scenario fill:
#9B8EC4 with alpha=0.08
Single Forecast Plot
plot_forecast_single creates a one-window figure with optional ground truth,
metrics badge, and text summary panel below the chart.
fig, ax = plot_forecast_single(
history,
gt_vals,
{"Chronos-2": chronos_fc, "Migas-1.5": migas_fc},
context_len,
pred_len,
title="Chronos-2 vs. Migas-1.5",
figsize=(11, 4),
show_metrics=True,
text_summary=summary,
timestamps=full["t"].values,
)
plt.show()
Key behaviors:
- When
timestamps is provided (length = context_len + pred_len), the x-axis shows dates
- When
text_summary is provided, a styled text panel is added below the chart
- When
show_metrics=True and ground truth exists, a MAPE/MAE badge appears above the title
- Migas-1.5 is always drawn on top (highest z-order)
Grid of Forecast Windows
plot_forecast_grid creates a multi-subplot figure for comparing multiple windows
(e.g. from a backtest or batch run).
fig, axes = plot_forecast_grid(
history_2d,
gt_2d,
{"Migas-1.5": migas_2d, "Chronos-2": chronos_2d},
context_len,
pred_len,
sample_indices=[0, 1, 2, 3],
titles=["Window 1", "Window 2", "Window 3", "Window 4"],
max_cols=3,
show_metrics=True,
)
plt.show()
Forecast Region Shading
_draw_forecast_region adds a warm-tinted background band and vertical divider
to mark the forecast zone. Used internally by the plot functions, but can be
called directly for custom plots:
_draw_forecast_region(
ax, context_len, pred_len,
boundary=t_pred[0],
boundary_end=t_pred[-1],
)
Counterfactual Scenario Fan (Custom Plot)
For the scenario fan plot (original + bullish + bearish), build it manually since
it needs custom colors and fill. Pattern from the notebooks:
import matplotlib.dates as mdates
fig, ax = plt.subplots(figsize=(11, 5))
_draw_forecast_region(ax, CONTEXT_LEN, PRED_LEN, boundary=t_pred[0], boundary_end=t_pred[-1])
ax.plot(t_ctx, context_vals, color=COLORS["historical"], lw=2.0, label="Historical")
ax.plot(t_pred, np.concatenate([[last_val], gt_vals]),
color=COLORS["ground_truth"], lw=2.2, label="Ground Truth")
ax.plot(t_pred, np.concatenate([[last_val], fc_original]),
color=COLORS["Migas-1.5"], lw=2.0, ls="--", alpha=0.85, label="Original (Migas-1.5)")
ax.plot(t_pred, np.concatenate([[last_val], fc_bullish]),
color="#2EAD6D", lw=2.4, label="Bullish scenario")
ax.plot(t_pred, np.concatenate([[last_val], fc_bearish]),
color="#C0392B", lw=2.4, label="Bearish scenario")
ax.fill_between(t_pred,
np.concatenate([[last_val], fc_bearish]),
np.concatenate([[last_val], fc_bullish]),
alpha=0.08, color="#9B8EC4", label="Scenario range")
ax.xaxis.set_major_formatter(mdates.ConciseDateFormatter(ax.xaxis.get_major_locator()))
ax.legend(fontsize=8, handlelength=1.6)
fig.tight_layout(pad=1.2)
plt.show()
Important Notes
- Always prepend
last_val (the last context value) to forecast arrays when plotting
prediction lines — this connects the forecast to the historical line visually:
np.concatenate([[last_val], forecast])
t_pred should have length pred_len + 1 to match the prepended arrays
- For date x-axes, rotate labels:
lbl.set_rotation(35); lbl.set_ha("right")
- Denormalization is built-in: pass
history_mean and history_std to automatically
rescale values back to original units