kdiagram.plot.comparison.plot_horizon_metrics¶
- kdiagram.plot.comparison.plot_horizon_metrics(df, qlow_cols, qup_cols, *, q50_cols=None, xtick_labels=None, normalize_radius=False, show_value_labels=True, cbar_label=None, r_label=None, cmap='coolwarm', acov='default', title=None, figsize=(8.0, 8.0), alpha=0.85, show_grid=True, grid_props=None, mask_angle=False, savefig=None, dpi=300, cbar=True, ax=None)[source]¶
Plot a polar bar chart comparing metrics across different horizons.
This function visualizes a primary metric (typically mean interval width) as the height of bars arranged in a circle. Each bar represents a distinct category or forecast horizon. A secondary metric (typically the mean Q50 value) can be encoded as the color of the bars, providing a multi-faceted comparison.
- Parameters:
- df
pd.DataFrame Input DataFrame where each row represents a distinct horizon or category to be compared.
- qlow_cols
listofstr List of column names containing lower quantile samples (e.g., Q10) for each horizon.
- qup_cols
listofstr List of column names containing upper quantile samples (e.g., Q90). Must have the same length as
qlow_cols.- q50_cols
listofstr,optional List of column names for the median quantile (Q50). If provided, the mean of these values determines the bar color. If
None, bar color is determined by the bar height (the mean interval width).- xtick_labels
listofstr,optional Custom labels for each bar on the angular axis. The length must match the number of rows in
df. IfNone, no angular labels are shown.- normalize_radiusbool, default=False
If
True, the radial values (bar heights) are min-max scaled to the range[0, 1].- show_value_labelsbool, default=True
If
True, display the numeric value of the radial metric on top of each bar.- cbar_label
str,optional Custom label for the color bar. If
None, a default label is generated.- r_label
str,optional Custom label for the radial axis.
- cmap
str, default=’coolwarm’ Matplotlib colormap name for coloring the bars.
- acov{‘default’, ‘half_circle’, ‘quarter_circle’,
- ‘eighth_circle’}, default=’default’
Specifies the angular coverage of the plot:
'default'(360°),'half_circle'(180°), etc.- title
str,optional Title for the plot. If
None, a default title is used.- figsize
tupleof(float,float), default=(8, 8) Figure size in inches.
- alpha
float, default=0.85 Transparency level for the bars.
- show_gridbool, default=True
Toggle gridlines via the package helper
set_axis_grid.- grid_props
dict,optional Keyword arguments passed to
set_axis_gridfor grid customization.- mask_anglebool, default=False
If
Trueandxtick_labelsis not provided, this will hide any default angular tick labels.- savefig
str,optional If provided, save the figure to this path; otherwise the plot is shown interactively.
- dpi
int, default=300 Resolution for the saved figure.
- cbarbool, default=True
If
True, display a color bar.
- df
- Returns:
- ax
matplotlib.axes.Axes The Matplotlib Axes object containing the polar bar plot.
- ax
- Parameters:
df (DataFrame)
normalize_radius (bool)
show_value_labels (bool)
cbar_label (str | None)
r_label (str | None)
cmap (str)
acov (Literal['default', 'half_circle', 'quarter_circle', 'eighth_circle'])
title (str | None)
alpha (float)
show_grid (bool)
grid_props (dict | None)
mask_angle (bool)
savefig (str | None)
dpi (int)
cbar (bool)
ax (Axes | None)
Notes
The plot summarizes metrics for \(N\) horizons (rows) using data from \(M\) samples (columns). Let \(\mathbf{L}\), \(\mathbf{U}\), and \(\mathbf{Q50}\) be data matrices of shape \((N, M)\) extracted from the corresponding columns.
Interval Width Calculation: For each horizon \(j\) and sample \(i\), the interval width is:
(1)¶\[W_{j,i} = U_{j,i} - L_{j,i}\]Radial Value (Bar Height): The radial value \(r_j\) for horizon \(j\) is the mean interval width across all \(M\) samples.
(2)¶\[r_j = \frac{1}{M} \sum_{i=0}^{M-1} W_{j,i}\]Color Value: The color value \(c_j\) for horizon \(j\) is determined by the mean of the
q50_colsvalues.(3)¶\[c_j = \frac{1}{M} \sum_{i=0}^{M-1} Q50_{j,i}\]If
q50_colsis not provided, the color defaults to the radial value, \(c_j = r_j\).Angular Position: Horizons are spaced evenly around the circle. For horizon \(j\), the angle is:
(4)¶\[\theta_j = \frac{j}{N} \times S\]where \(S\) is the angular span from
acov. The plot starts at the top (12 o’clock) and proceeds clockwise.
Examples
>>> import numpy as np >>> import pandas as pd >>> from kdiagram.plot import plot_horizon_metrics >>> >>> # Create synthetic data for 6 horizons with 2 samples each >>> horizons = ["H+1", "H+2", "H+3", "H+4", "H+5", "H+6"] >>> df = pd.DataFrame({ ... 'q10_s1': [1, 2, 3, 4, 5, 6], ... 'q10_s2': [1.2, 2.3, 3.4, 4.5, 5.6, 6.7], ... 'q90_s1': [3, 4, 5.5, 7, 8, 9.5], ... 'q90_s2': [3.1, 4.2, 5.7, 7.3, 8.4, 9.9], ... 'q50_s1': [2, 3, 4.2, 5.7, 6.5, 8.2], ... 'q50_s2': [2.1, 3.2, 4.4, 5.9, 6.9, 8.8], ... }) >>> >>> q10_cols = ['q10_s1', 'q10_s2'] >>> q90_cols = ['q90_s1', 'q90_s2'] >>> q50_cols = ['q50_s1', 'q50_s2'] >>> >>> ax = plot_horizon_metrics( ... df=df, ... qlow_cols=q10_cols, ... qup_cols=q90_cols, ... q50_cols=q50_cols, ... title="Mean Interval Width Across Horizons", ... xtick_labels=horizons, ... show_value_labels=True, ... r_label="Mean Interval Width (Q90-Q10)", ... cbar_label="Mean Q50 Value", ... acov="default" ... )