kdiagram.plot.uncertainty.plot_radial_density_ring

kdiagram.plot.uncertainty.plot_radial_density_ring(df, *, kind='direct', target_cols, title=None, r_label=None, figsize=(8.0, 8.0), cmap='viridis', alpha=0.8, cbar=True, acov='default', show_grid=True, grid_props=None, mask_angle=True, bandwidth=None, savefig=None, dpi=300, show_yticklabels=False, ax=None)[source]

Plot a radial density ring to visualize a 1D distribution.

This function computes the probability density function (PDF) of a one-dimensional variable using Kernel Density Estimation (KDE) and visualizes it as a colored ring on a polar plot. It’s a powerful way to inspect the shape, peaks, and spread of a distribution, such as forecast errors or interval widths.

  • Radial Distance (`r`): Represents the domain of the variable being analyzed (e.g., interval width in mm).

  • Color: Represents the probability density at each radial position. More intense colors indicate more common values (peaks in the distribution).

  • Angular Position (`theta`): Is purely for aesthetics and carries no information; the density is uniform around the circle to form the ring.

Parameters:
dfpd.DataFrame

The input DataFrame containing the data.

kind{‘width’, ‘velocity’, ‘direct’}, default=’direct’

Specifies how to derive the 1D data for the distribution plot from the target_cols.

  • 'direct': Directly uses the data from a single column specified in target_cols.

  • 'width': Calculates the interval width by subtracting the first column from the second in target_cols (e.g., q90 - q10).

  • 'velocity': Calculates the difference between two columns, representing a change or velocity (e.g., value_t2 - value_t1).

target_colsstr or list of str

The column(s) to use for deriving the data.

  • For kind='direct', this must be a single column name (str).

  • For kind='width' or kind='velocity', this must be a list of exactly two column names ([col1, col2]).

titlestr, optional

The title for the plot. If None, a default is generated.

r_labelstr, optional

Custom label for the radial axis. If None, a default is generated from the column names.

figsizetuple of (float, float), default=(8, 8)

Figure size in inches.

cmapstr, default=’viridis’

Matplotlib colormap name for the density ring.

alphafloat, default=0.8

Transparency level for the density ring.

cbarbool, default=True

If True, display a color bar representing the normalized density.

acov{‘default’, ‘half_circle’, ‘quarter_circle’,

‘eighth_circle’}, default=’default’ Angular coverage of the polar sector.

  • 'default' : full circle, \(2\pi\) (360°)

  • 'half_circle' : \(\pi\) (180°)

  • 'quarter_circle' : \(\pi/2\) (90°)

  • 'eighth_circle' : \(\pi/4\) (45°)

By convention, the radial density ring uses a full 360° sector. If a non-default value is provided, a short warning is issued.

show_gridbool, default=True

Toggle gridlines via the package helper set_axis_grid.

grid_propsdict, optional

Keyword arguments passed to set_axis_grid for grid customization.

mask_anglebool, default=True

If False, show the tick labels on the radial axis. Defaults to True as the ring is primarily a qualitative visual.

bandwidthfloat, optional

The bandwidth for the Kernel Density Estimation. If None, it is estimated using Silverman’s rule of thumb.

savefigstr, optional

If provided, save the figure to this path; otherwise the plot is shown interactively.

dpiint, default=300

Resolution for the saved figure.

Returns:
axmatplotlib.axes.Axes or None

The Matplotlib Axes object containing the plot, or None if the plot could not be generated (e.g., due to empty data).

Parameters:
Return type:

Axes | None

Notes

The plot is generated through the following steps:

  1. Data Derivation: A one-dimensional data vector, \(\mathbf{x}\), is created from the target_cols based on the specified kind.

  2. Kernel Density Estimation: The probability density function (PDF), \(\hat{f}_h(x)\), is estimated from the data vector \(\mathbf{x}\) using a Gaussian kernel. This step is handled by scipy.stats.gaussian_kde.

  3. Normalization for Coloring: The estimated PDF is normalized to the range [0, 1] to map its values to the color map.

    (1)\[\text{PDF}_{\text{norm}}(x) = \frac{\hat{f}_h(x)}{\max(\hat{f}_h)}\]
  4. Visualization: The plot is rendered on polar axes using pcolormesh. The radial axis corresponds to the value domain \(x\), and the color at each radius corresponds to \(\text{PDF}_{\text{norm}}(x)\). This color value is repeated across all angles to form a ring.

Examples

>>> import numpy as np
>>> import pandas as pd
>>> from kdiagram.plot.uncertainty import plot_radial_density_ring
>>>
>>> # Create synthetic data
>>> np.random.seed(42)
>>> n_samples = 500
>>> df_test = pd.DataFrame({
...     'q10_pred': np.random.normal(10, 2, n_samples),
...     'q90_pred': np.random.normal(30, 3, n_samples),
... })
>>> # Ensure upper bound is greater than lower bound
>>> df_test['q90_pred'] = df_test[['q10_pred', 'q90_pred']].max(axis=1) \
...     + np.random.rand(n_samples)
>>>
>>> # Generate the plot for the distribution of interval widths
>>> ax = plot_radial_density_ring(
...     df=df_test,
...     kind="width",
...     target_cols=["q10_pred", "q90_pred"],
...     title="Distribution of Prediction Interval Width",
...     r_label="Interval Width (mm)",
...     cmap="magma",
...     show_yticklabels=True
... )