kdiagram.plot.relationship.plot_residual_relationship

kdiagram.plot.relationship.plot_residual_relationship(y_true, *y_preds, names=None, title='Residual vs. Predicted Relationship', figsize=(8.0, 8.0), cmap='viridis', s=50, alpha=0.7, show_zero_line=True, show_grid=True, grid_props=None, savefig=None, dpi=300, mask_angle=False, mask_radius=False, acov='default', ax=None)[source]

Plots the relationship between forecast error and predicted value.

This function creates a polar scatter plot, a polar version of a classic residual plot, to diagnose model performance. The angle is proportional to the predicted value, and the radius represents the forecast error. It is a powerful tool for identifying conditional biases and heteroscedasticity related to the model’s own output magnitude.

Parameters:
y_truenp.ndarray

1D array of true observed values.

*y_predsnp.ndarray

One or more 1D arrays of predicted values from different models.

nameslist of str, optional

Display names for each of the models. If not provided, generic names like 'Model 1' will be generated.

titlestr, default=”Residual vs. Predicted Relationship”

The title for the plot.

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

The figure size in inches.

cmapstr, default=’viridis’

The colormap used to assign a unique color to each model’s markers.

sint, default=50

The size of the scatter plot markers.

alphafloat, default=0.7

The transparency of the markers.

show_zero_linebool, default=True

If True, draws a reference circle representing zero error.

show_gridbool, default=True

Toggle the visibility of the polar grid lines.

grid_propsdict, optional

Custom keyword arguments passed to the grid for styling.

savefigstr, optional

The file path to save the plot. If None, the plot is displayed interactively.

dpiint, default=300

The resolution (dots per inch) for the saved figure.

mask_anglebool, default=False

If True, hide the angular tick labels.

mask_radiusbool, default=False

If True, hide the radial tick labels.

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

default=’default’ Angular coverage (span) of the plot:

  • 'default': \(2\pi\) (full circle)

  • 'half_circle': \(\pi\)

  • 'quarter_circle': \(\tfrac{\pi}{2}\)

  • 'eighth_circle': \(\tfrac{\pi}{4}\)

Returns:
axmatplotlib.axes.Axes

The Matplotlib Axes object containing the plot.

Parameters:

See also

plot_error_relationship

Plot error vs. the true value.

plot_conditional_quantiles

Visualize full conditional quantile bands.

Notes

This plot is a novel visualization developed as part of the analytics framework in [1]. It helps diagnose if the model’s error is correlated with its own predictions.

  1. Error (Residual) Calculation: For each observation \(i\), the error is the difference between the true and predicted value.

    (1)\[e_i = y_{true,i} - y_{pred,i}\]
  2. Angular Mapping: The angle \(\theta_i\) is made proportional to the predicted value \(y_{pred,i}\), after sorting, to create a continuous spiral.

    (2)\[\theta_i \propto y_{pred,i}\]
  3. Radial Mapping: The radius \(r_i\) represents the error \(e_i\). To handle negative error values on a polar plot, an offset is added to all radii so that the zero-error line becomes a reference circle.

References

Examples

>>> import numpy as np
>>> from kdiagram.plot.relationship import plot_residual_relationship
>>>
>>> # Generate synthetic data with known flaws
>>> np.random.seed(0)
>>> n_samples = 200
>>> y_true = np.linspace(0, 20, n_samples)**1.5
>>> # Model has errors that increase with the prediction magnitude
>>> noise = np.random.normal(0, 1, n_samples) * (y_true / 20)
>>> y_pred = y_true + noise
>>>
>>> # Generate the plot
>>> ax = plot_residual_relationship(
...     y_true,
...     y_pred,
...     names=["My Model"],
...     title="Residual vs. Predicted Value (Heteroscedasticity)"
... )