import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.patches import Rectangle
# Walk-forward illustration: Rolling 10-year window, predict 1 year ahead
fig, ax = plt.subplots(figsize=(14, 6))
# Show consecutive rolling windows (the actual process)
window_size = 10
examples = [
(2011, 2001, 2010), # Step 1: Train 2001-2010, predict 2011
(2012, 2002, 2011), # Step 2: Train 2002-2011, predict 2012
(2013, 2003, 2012), # Step 3: Train 2003-2012, predict 2013
(2014, 2004, 2013), # Step 4: Train 2004-2013, predict 2014
(2015, 2005, 2014), # Step 5: Train 2005-2014, predict 2015
]
colors = plt.cm.Blues(np.linspace(0.3, 0.7, len(examples)))
for idx, (forecast_year, train_start, train_end) in enumerate(examples):
y_pos = (len(examples) - 1 - idx) * 1.2
# Training window
train_width = train_end - train_start + 1
ax.add_patch(Rectangle((train_start, y_pos), train_width - 0.1, 0.8,
facecolor=colors[idx], edgecolor='black', linewidth=1.5))
ax.text(train_start + train_width/2 - 0.5, y_pos + 0.4, f'Train: {train_start}-{train_end}',
ha='center', va='center', fontsize=9, fontweight='bold')
# Forecast point (one year ahead)
ax.scatter([forecast_year], [y_pos + 0.4], s=150, c='red', marker='*',
edgecolors='darkred', linewidths=1, zorder=10)
ax.annotate(f'{forecast_year}', (forecast_year, y_pos + 0.4),
xytext=(forecast_year + 0.8, y_pos + 0.4),
fontsize=8, fontweight='bold', color='red',
va='center')
ax.set_xlim(1999, 2017)
ax.set_ylim(-0.5, 6.5)
ax.set_xlabel('Year', fontsize=11, fontweight='bold')
ax.set_title('Walk-Forward Validation: Rolling 10-Year Window (Predict 1 Year Ahead)',
fontsize=12, fontweight='bold', pad=15)
ax.set_yticks([])
ax.grid(axis='x', alpha=0.3, linestyle='--')
# Add timeline
for year in range(2000, 2017, 2):
ax.axvline(x=year, color='gray', alpha=0.2, linestyle=':')
ax.text(year, -0.3, str(year), ha='center', fontsize=8)
# Add annotation showing the "roll"
ax.annotate('Window rolls forward\none year at a time',
xy=(2006, 3), fontsize=9, style='italic',
bbox=dict(boxstyle='round', facecolor='wheat', alpha=0.5))
plt.tight_layout()
# Note: plt.show() not needed - Quarto captures figures automatically