kdiagram.plot.errors.plot_error_ellipses

kdiagram.plot.errors.plot_error_ellipses(df, r_col, theta_col, r_std_col, theta_std_col, *, color_col=None, n_std=2.0, title=None, figsize=(8.0, 8.0), cmap='viridis', mask_angle=False, mask_radius=False, show_grid=True, grid_props=None, savefig=None, dpi=300, acov='default', ax=None, **ellipse_kws)[source]

Plot polar error ellipses to visualize two-dimensional uncertainty.

This function draws ellipses on a polar plot to represent the uncertainty of data points where both the radial and angular components have associated errors (standard deviations).

Parameters:
dfpd.DataFrame

Input DataFrame containing the data for the plot.

r_colstr

Name of the column for the mean radial position (e.g., distance).

theta_colstr

Name of the column for the mean angular position. Must be in degrees.

r_std_colstr

Name of the column for the standard deviation of the radial position.

theta_std_colstr

Name of the column for the standard deviation of the angular position. Must be in degrees.

color_colstr, optional

Name of a column to use for coloring the ellipses. If None, ellipses are colored by their radial uncertainty (r_std_col).

n_stdfloat, default=2.0

The number of standard deviations to use for the ellipse size. For example, n_std=2.0 corresponds to approximately a 95% confidence region for a normal distribution.

titlestr, optional

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

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

Figure size in inches.

cmapstr, default=’viridis’

Matplotlib colormap for coloring the ellipses.

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=False

If True, hide the angular tick labels (degrees).

mask_radiusbool, default=False

If True, hide the radial tick labels.

savefigstr, optional

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

dpiint, default=300

Resolution for the saved figure.

**ellipse_kwsdict, optional

Additional keyword arguments passed to the ax.fill call for each ellipse (e.g., alpha, edgecolor).

Returns:
axmatplotlib.axes.Axes or None

The Matplotlib Axes object containing the plot, or None if the plot could not be generated.

Parameters:

Notes

The visualization for each data point \(i\) is constructed from its mean radial position \(\mu_{r,i}\), mean angular position \(\mu_{\theta,i}\), and their respective standard deviations \(\sigma_{r,i}\) and \(\sigma_{\theta,i}\).

  1. Ellipse Dimensions: The ellipse is first defined in a local Cartesian coordinate system at the origin. Its half-width (along the radial direction) and half-height (along the tangential direction) are determined by the standard deviations:

    (1)\[\begin{split}\text{width} &= n_{std} \cdot \sigma_{r,i} \\ \text{height} &= n_{std} \cdot (\mu_{r,i} \cdot \sin(\sigma_{\theta,i}))\end{split}\]

    Note that the tangential height depends on the radial distance \(\mu_{r,i}\).

  2. Transformation: This local ellipse is then transformed to the correct position on the polar plot. This involves two steps:

    1. Rotation: The ellipse is rotated by the mean angle \(\mu_{\theta,i}\) to align its primary axis with the radial direction from the origin.

    2. Translation: The rotated ellipse is translated to the mean position, which in Cartesian coordinates is \((x_c, y_c) = (\mu_{r,i} \cos(\mu_{\theta,i}), \mu_{r,i} \sin(\mu_{\theta,i}))\).

  3. Plotting: The final transformed ellipse is drawn as a filled path on the polar axes.

Examples

>>> import numpy as np
>>> import pandas as pd
>>> from kdiagram.plot.errors import plot_polar_error_ellipses
>>>
>>> # Simulate tracking data for 15 objects
>>> np.random.seed(1)
>>> n_points = 15
>>> df_tracking = pd.DataFrame({
...     'angle_deg': np.linspace(0, 360, n_points, endpoint=False),
...     'distance_km': np.random.uniform(20, 80, n_points),
...     'distance_std': np.random.uniform(2, 7, n_points),
...     'angle_std_deg': np.random.uniform(3, 10, n_points),
...     'object_priority': np.random.randint(1, 5, n_points)
... })
>>>
>>> # Generate the plot
>>> ax = plot_polar_error_ellipses(
...     df=df_tracking,
...     r_col='distance_km',
...     theta_col='angle_deg',
...     r_std_col='distance_std',
...     theta_std_col='angle_std_deg',
...     color_col='object_priority',
...     n_std=1.5,
...     title='1.5-Sigma Positional Uncertainty',
...     cmap='cividis',
...     alpha=0.7,
...     edgecolor='black',
...     linewidth=0.5
... )