0
# Visualization
1
2
Plotting utilities for visualizing hierarchical time series data, reconciliation results, and hierarchy structures. The visualization tools help explore hierarchical relationships, compare forecasts across methods, and understand the impact of reconciliation.
3
4
## Capabilities
5
6
### HierarchicalPlot Class
7
8
Main visualization class that provides methods for plotting hierarchical time series data and reconciliation results.
9
10
```python { .api }
11
class HierarchicalPlot:
12
"""
13
Visualization utilities for hierarchical forecasts.
14
15
Provides plotting methods for exploring hierarchical time series data,
16
reconciliation results, and hierarchy structures.
17
"""
18
19
def __init__(
20
self,
21
S: Frame,
22
tags: dict[str, np.ndarray],
23
S_id_col: str = 'unique_id'
24
):
25
"""
26
Initialize HierarchicalPlot object.
27
28
Parameters:
29
- S: DataFrame representing the summing matrix
30
- tags: dict mapping hierarchy level names to series indices
31
- S_id_col: str, column name for series identifier in summing matrix
32
"""
33
```
34
35
### Summing Matrix Visualization
36
37
Visualize the structure of the summing matrix to understand hierarchical relationships.
38
39
```python { .api }
40
def plot_summing_matrix(self) -> None:
41
"""
42
Visualize the summing matrix structure.
43
44
Creates a heatmap showing the aggregation relationships between
45
bottom-level series and all hierarchy levels. Useful for understanding
46
the hierarchical structure and identifying potential issues.
47
48
The plot shows:
49
- Rows: All series in the hierarchy (bottom and aggregated)
50
- Columns: Bottom-level series
51
- Values: Binary indicators (1 if bottom series contributes to aggregate, 0 otherwise)
52
"""
53
```
54
55
### Individual Series Plotting
56
57
Plot individual time series with forecasts and prediction intervals.
58
59
```python { .api }
60
def plot_series(
61
self,
62
series: str,
63
Y_df: Frame,
64
models: list[str] = None,
65
level: list[int] = None,
66
engine: str = 'matplotlib',
67
xlabel: str = None,
68
ylabel: str = None,
69
title: str = None,
70
id_col: str = 'unique_id',
71
time_col: str = 'ds',
72
target_col: str = 'y',
73
**kwargs
74
) -> None:
75
"""
76
Plot individual time series with forecasts.
77
78
Parameters:
79
- series: str, name of the series to plot
80
- Y_df: DataFrame with historical data and forecasts
81
- models: list of model names to include in plot
82
- level: list of confidence levels for prediction intervals
83
- engine: str, plotting engine ('matplotlib' or 'plotly')
84
- xlabel: str, x-axis label
85
- ylabel: str, y-axis label
86
- title: str, plot title
87
- id_col: str, identifier column name
88
- time_col: str, time column name
89
- target_col: str, target variable column name
90
- **kwargs: additional plotting arguments
91
92
Creates a plot showing:
93
- Historical values (if available)
94
- Point forecasts for each model
95
- Prediction intervals (if level specified)
96
- Legend identifying different models and intervals
97
"""
98
```
99
100
### Hierarchically Linked Series Plotting
101
102
Plot all series in the hierarchy that are linked to a specific bottom-level series.
103
104
```python { .api }
105
def plot_hierarchically_linked_series(
106
self,
107
bottom_series: str,
108
Y_df: Frame,
109
models: list[str] = None,
110
level: list[int] = None,
111
engine: str = 'matplotlib',
112
xlabel: str = None,
113
ylabel: str = None,
114
id_col: str = 'unique_id',
115
time_col: str = 'ds',
116
target_col: str = 'y',
117
**kwargs
118
) -> None:
119
"""
120
Plot all series hierarchically linked to a bottom series.
121
122
Parameters:
123
- bottom_series: str, name of the bottom-level series
124
- Y_df: DataFrame with hierarchical data and forecasts
125
- models: list of model names to plot
126
- level: list of confidence levels for intervals
127
- engine: str, plotting engine
128
- xlabel: str, x-axis label
129
- ylabel: str, y-axis label
130
- id_col: str, identifier column name
131
- time_col: str, time column name
132
- target_col: str, target variable column name
133
- **kwargs: additional plotting arguments
134
135
Creates subplots showing:
136
- The specified bottom series
137
- All aggregate series that include this bottom series
138
- Forecasts and intervals for each hierarchy level
139
"""
140
```
141
142
### Hierarchical Predictions Gap Plotting
143
144
Visualize prediction gaps across different hierarchy levels to assess reconciliation quality.
145
146
```python { .api }
147
def plot_hierarchical_predictions_gap(
148
self,
149
Y_df: Frame,
150
models: list[str] = None,
151
xlabel: str = None,
152
ylabel: str = None,
153
id_col: str = 'unique_id',
154
time_col: str = 'ds',
155
**kwargs
156
) -> None:
157
"""
158
Plot prediction gaps across hierarchy levels.
159
160
Parameters:
161
- Y_df: DataFrame with forecasts at different hierarchy levels
162
- models: list of model names to analyze
163
- xlabel: str, x-axis label
164
- ylabel: str, y-axis label
165
- id_col: str, identifier column name
166
- time_col: str, time column name
167
- **kwargs: additional plotting arguments
168
169
Creates visualization showing:
170
- Differences between aggregated bottom-up forecasts and direct forecasts
171
- Gap magnitude across different hierarchy levels
172
- Comparison across reconciliation methods
173
- Time evolution of coherence gaps
174
"""
175
```
176
177
### Code Timer Utility
178
179
Context manager for timing code execution, useful for performance analysis.
180
181
```python { .api }
182
class CodeTimer:
183
"""
184
Context manager for timing code execution.
185
186
Useful for measuring performance of reconciliation methods
187
and data processing operations.
188
"""
189
190
def __init__(self, name: str = None):
191
"""
192
Initialize CodeTimer.
193
194
Parameters:
195
- name: str, optional name for the timer (for identification)
196
"""
197
198
def __enter__(self):
199
"""Start timing when entering context."""
200
return self
201
202
def __exit__(self, exc_type, exc_val, exc_tb):
203
"""Stop timing and report duration when exiting context."""
204
```
205
206
## Usage Examples
207
208
### Basic Visualization Setup
209
210
```python
211
import pandas as pd
212
import numpy as np
213
from hierarchicalforecast.utils import HierarchicalPlot
214
215
# Assume we have hierarchical data and forecasts
216
hierarchical_data = pd.DataFrame({
217
'unique_id': ['A', 'B', 'Total'] * 10,
218
'ds': pd.date_range('2020-01-01', periods=10, freq='D').tolist() * 3,
219
'y': np.random.randn(30).cumsum() + 100,
220
'BottomUp': np.random.randn(30).cumsum() + 100,
221
'MinTrace': np.random.randn(30).cumsum() + 100
222
})
223
224
# Tags mapping hierarchy levels
225
tags = {
226
'Bottom': np.array([0, 1]), # Series A and B
227
'Total': np.array([2]) # Aggregated series
228
}
229
230
# Summing matrix
231
S_df = pd.DataFrame({
232
'unique_id': ['A', 'B', 'Total'],
233
'A': [1, 0, 1],
234
'B': [0, 1, 1]
235
})
236
237
# Create plotting object
238
plotter = HierarchicalPlot(S=S_df, tags=tags)
239
```
240
241
### Visualize Hierarchy Structure
242
243
```python
244
# Plot the summing matrix to understand hierarchy structure
245
plotter.plot_summing_matrix()
246
```
247
248
### Plot Individual Series
249
250
```python
251
# Plot a specific series with multiple models
252
plotter.plot_series(
253
series='Total',
254
Y_df=hierarchical_data,
255
models=['BottomUp', 'MinTrace'],
256
title='Total Series Forecasts',
257
xlabel='Date',
258
ylabel='Value'
259
)
260
```
261
262
### Plot with Prediction Intervals
263
264
```python
265
# Data with prediction intervals
266
data_with_intervals = hierarchical_data.copy()
267
data_with_intervals['BottomUp-lo-80'] = data_with_intervals['BottomUp'] - 10
268
data_with_intervals['BottomUp-hi-80'] = data_with_intervals['BottomUp'] + 10
269
data_with_intervals['MinTrace-lo-80'] = data_with_intervals['MinTrace'] - 8
270
data_with_intervals['MinTrace-hi-80'] = data_with_intervals['MinTrace'] + 8
271
272
# Plot with intervals
273
plotter.plot_series(
274
series='Total',
275
Y_df=data_with_intervals,
276
models=['BottomUp', 'MinTrace'],
277
level=[80], # 80% prediction intervals
278
title='Forecasts with Prediction Intervals'
279
)
280
```
281
282
### Plot Hierarchically Linked Series
283
284
```python
285
# Show all series linked to bottom series 'A'
286
plotter.plot_hierarchically_linked_series(
287
bottom_series='A',
288
Y_df=hierarchical_data,
289
models=['BottomUp', 'MinTrace'],
290
xlabel='Date',
291
ylabel='Value'
292
)
293
```
294
295
### Analyze Reconciliation Quality
296
297
```python
298
# Plot prediction gaps to assess reconciliation quality
299
plotter.plot_hierarchical_predictions_gap(
300
Y_df=hierarchical_data,
301
models=['BottomUp', 'MinTrace'],
302
xlabel='Date',
303
ylabel='Gap Magnitude'
304
)
305
```
306
307
### Using Different Plotting Engines
308
309
```python
310
# Use plotly for interactive plots (if available)
311
plotter.plot_series(
312
series='Total',
313
Y_df=hierarchical_data,
314
models=['BottomUp', 'MinTrace'],
315
engine='plotly',
316
title='Interactive Forecast Plot'
317
)
318
```
319
320
### Performance Timing
321
322
```python
323
from hierarchicalforecast.utils import CodeTimer
324
325
# Time reconciliation operations
326
with CodeTimer("MinTrace Reconciliation"):
327
reconciled = min_trace.fit_predict(
328
S=summing_matrix,
329
y_hat=forecasts,
330
y_insample=historical_data
331
)
332
333
# Time multiple operations
334
operations = {
335
'BottomUp': lambda: bottom_up.fit_predict(S, forecasts, bottom_indices),
336
'TopDown': lambda: top_down.fit_predict(S, forecasts, tags, historical_data),
337
'MinTrace': lambda: min_trace.fit_predict(S, forecasts, historical_data)
338
}
339
340
timing_results = {}
341
for name, operation in operations.items():
342
with CodeTimer(name) as timer:
343
result = operation()
344
timing_results[name] = timer.elapsed_time
345
```
346
347
### Customizing Plots
348
349
```python
350
# Custom styling and additional parameters
351
plotter.plot_series(
352
series='Total',
353
Y_df=hierarchical_data,
354
models=['BottomUp', 'MinTrace'],
355
title='Custom Styled Forecast Plot',
356
xlabel='Time Period',
357
ylabel='Sales Units',
358
figsize=(12, 6), # Custom figure size
359
linewidth=2, # Line width
360
alpha=0.7, # Transparency
361
grid=True, # Show grid
362
legend_loc='upper left' # Legend position
363
)
364
```
365
366
### Comparing Multiple Hierarchy Levels
367
368
```python
369
# Create plots for each hierarchy level
370
hierarchy_levels = ['A', 'B', 'Total']
371
372
for level in hierarchy_levels:
373
plotter.plot_series(
374
series=level,
375
Y_df=hierarchical_data,
376
models=['BottomUp', 'MinTrace'],
377
title=f'Forecasts for {level}',
378
ylabel='Value'
379
)
380
```