kdiagram.plot.anomaly.plot_glyphs

kdiagram.plot.anomaly.plot_glyphs(df, actual_col, q_low_col, q_up_col, *, sort_by=None, window_size=21, title=None, figsize=(9.0, 9.0), cmap='inferno', s=70, alpha=0.85, acov='default', mask_angle=True, mask_radius=False, show_grid=True, grid_props=None, radius='severity', color_by='local_density', vmin=None, vmax=None, zero_at='N', clockwise=True, ax=None, savefig=None, **kwargs)[source]

Visualizes anomaly characteristics using a polar glyph plot.

This function creates a highly informative diagnostic plot where each data point is represented by a glyph (a custom symbol) on a polar axis. The glyph’s properties—location, size, shape, and color—encode multiple dimensions of the data, offering a clear and scientifically rigorous visualization of forecast failures or other phenomena.

Parameters:
dfpd.DataFrame

The input DataFrame containing the actual and predicted quantile values.

actual_colstr

Name of the column containing the true observed values.

q_low_colstr

Name of the column for the lower bound of the prediction interval.

q_up_colstr

Name of the column for the upper bound of the prediction interval.

sort_bystr or array_like, optional

The feature used to order points around the angular axis. Can be a column name or an external array. If None, the DataFrame’s index is used, which is suitable for time series.

window_sizeint, default=21

The size of the moving window used to calculate the local anomaly density, which can be used for coloring.

titlestr, optional

A custom title for the plot.

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

The figure size in inches.

cmapstr, default=’inferno’

The colormap for coloring glyphs.

sint, default=70

The base marker size for the glyphs.

alphafloat, default=0.85

The transparency of the glyphs.

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

default=’default’ Specifies the angular coverage of the polar plot.

mask_anglebool, default=True

If True, hides the angular tick labels.

mask_radiusbool, default=False

If True, hides the radial tick labels.

show_gridbool, default=True

If True, displays the polar grid lines.

grid_propsdict, optional

Custom keyword arguments to style the grid.

radius{‘magnitude’, ‘local_density’, ‘severity’}, default=’magnitude’

The data field to map to the radial coordinate (distance from the center).

color_bystr, default=’local_density’

The data field to map to the glyph color. Must be a column in the details DataFrame returned by the CAS metric.

vmin, vmaxfloat, optional

The minimum and maximum values for the color normalization. If None, they are inferred from the color_by data.

zero_at{‘N’, ‘E’, ‘S’, ‘W’}, default=’N’

The direction for the 0° angle on the polar plot.

clockwisebool, default=True

If True, angles increase in the clockwise direction.

axmatplotlib.axes.Axes, optional

An existing polar axes to draw the plot on.

savefigstr, optional

The file path to save the plot.

Returns:
axmatplotlib.axes.Axes or None

The Matplotlib Axes object containing the plot, or None if no anomalies are detected.

Parameters:
Return type:

Axes | None

See also

clustered_anomaly_severity

The underlying metric function.

plot_cas_layers

A Cartesian alternative showing anomaly layers.

Notes

This plot uses a glyph-based approach to encode multiple dimensions of information for each forecast failure.

Visual Mapping (Glyph Properties):

  • Angle (\(\varepsilon\)): The position in the sequence, ordered by the sort_by parameter.

  • Radius (`r`): The value of the column specified by radius, normalized to [0, 1]. A larger radius indicates a higher value for that metric.

  • Color: The value of the column specified by color_by. By default, hotter colors indicate a denser cluster of anomalies.

  • Shape: The Type of anomaly, using an intuitive metaphor:

    • (up-triangle): Over-prediction (risk “escaping” upward).

    • (down-triangle): Under-prediction (risk “collapsing” inward).

The plot also includes a thin gray line (show_path=True) that traces the radial metric along the sorted angular path, helping to visualize trends.

Examples

>>> import numpy as np
>>> import pandas as pd
>>> from kdiagram.plot.anomaly import plot_glyphs
>>>
>>> # Simulate data with a failure hotspot
>>> np.random.seed(0)
>>> n_samples = 200
>>> time = pd.to_datetime(pd.date_range(
...     "2024-01-01", periods=n_samples)
... )
>>> y_true = 50 + 10 * np.sin(np.arange(n_samples) * np.pi / 50)
>>> y_qlow = y_true - 5
>>> y_qup = y_true + 5
>>> y_true[80:100] = y_qup[80:100] + np.random.uniform(5, 10, 20)
>>>
>>> df = pd.DataFrame({
...     "time": time, "actual": y_true,
...     "q10": y_qlow, "q90": y_qup
... })
>>>
>>> ax = plot_glyphs(
...     df,
...     actual_col="actual",
...     q_low_col="q10",
...     q_up_col="q90",
...     sort_by="time",
...     radius="magnitude",
...     color_by="local_density",
...     title="Glyph Plot of Anomaly Hotspot"
... )