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:
- df
pd.DataFrame Input DataFrame containing the data for the plot.
- r_col
str Name of the column for the mean radial position (e.g., distance).
- theta_col
str Name of the column for the mean angular position. Must be in degrees.
- r_std_col
str Name of the column for the standard deviation of the radial position.
- theta_std_col
str Name of the column for the standard deviation of the angular position. Must be in degrees.
- color_col
str,optional Name of a column to use for coloring the ellipses. If
None, ellipses are colored by their radial uncertainty (r_std_col).- n_std
float, default=2.0 The number of standard deviations to use for the ellipse size. For example,
n_std=2.0corresponds to approximately a 95% confidence region for a normal distribution.- title
str,optional The title for the plot. If
None, a default is generated.- figsize
tupleof(float,float), default=(8, 8) Figure size in inches.
- cmap
str, default=’viridis’ Matplotlib colormap for coloring the ellipses.
- 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
True, hide the angular tick labels (degrees).- mask_radiusbool, default=False
If
True, hide the radial 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.
- **ellipse_kws
dict,optional Additional keyword arguments passed to the
ax.fillcall for each ellipse (e.g.,alpha,edgecolor).
- df
- Returns:
- ax
matplotlib.axes.AxesorNone The Matplotlib Axes object containing the plot, or
Noneif the plot could not be generated.
- ax
- Parameters:
df (DataFrame)
r_col (str)
theta_col (str)
r_std_col (str)
theta_std_col (str)
color_col (str | None)
n_std (float)
title (str | None)
cmap (str)
mask_angle (bool)
mask_radius (bool)
show_grid (bool)
savefig (str | None)
dpi (int)
acov (Literal['default', 'half_circle', 'quarter_circle', 'eighth_circle'])
ax (Axes | None)
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}\).
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}\).
Transformation: This local ellipse is then transformed to the correct position on the polar plot. This involves two steps:
Rotation: The ellipse is rotated by the mean angle \(\mu_{\theta,i}\) to align its primary axis with the radial direction from the origin.
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}))\).
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 ... )