explainer
Covariance and uncertainty ellipses: read the shape of error
Read a covariance matrix as a geometric description of spread. Rotate an uncertainty ellipse, compare a Gaussian model with a finite sample, and calculate what a 95% contour means.
What you will learn
- Read variances and cross-covariance with the correct units.
- Connect eigenvectors and eigenvalues to ellipse directions and semiaxes.
- Calculate Gaussian probability inside a two-dimensional contour.
- Distinguish model covariance from finite-sample covariance.
- Separate distribution spread from confidence in an estimated mean.
Before you start
- Eigenvectors and eigenvalues
- Gaussian distributions and standard deviation
A covariance matrix describes how quantities spread around their means and vary together. For a robot's planar position error, it tells you whether the scatter is wide, narrow, or tilted.
An uncertainty ellipse turns that matrix into a shape. Its probability meaning needs an extra assumption about the distribution. Here, a bivariate Gaussian model lets us calculate the mass inside each ellipse exactly.
What covariance describes
Let X and Y describe two position-error components, with means μₓ and μᵧ. Their covariance is the expected product of their deviations:
Cov(X, Y) = E[(X − μₓ)(Y − μᵧ)]
Positive covariance means same-sign deviations contribute more on average. Negative covariance means opposite-sign deviations contribute more. Zero covariance says that this centered product averages to zero.
Covariance can describe a physical distribution or a model of estimation error. A Kalman filter uses an error-covariance matrix to represent uncertainty under its model. Real accuracy still depends on the model and measurements.
Read the matrix and its units
Collect the two variances and their cross-covariance into a symmetric matrix:
Σ = [[σₓ², ρσₓσᵧ], [ρσₓσᵧ, σᵧ²]]
σₓ and σᵧ are standard deviations in meters. Every matrix entry here has units of m². The correlation coefficient ρ = Cov(X,Y) / (σₓσᵧ) is dimensionless, as in NIST's multivariate-normal definition.
A covariance matrix is positive semidefinite: every directional variance is nonnegative. Our lab requires positive standard deviations and |ρ| ≤ 0.95, making Σ positive definite and invertible. Perfect correlation can produce a singular matrix and a collapsed contour.
Coordinates matter. For a linear change of coordinates Y = AX, covariance transforms as Σᵧ = AΣₓAᵀ. A rotation changes the matrix entries and the ellipse's orientation relative to the axes; it preserves the physical spread.
Interpret correlation carefully
With equal positive deviations in x and y, a positive ρ tilts the long direction upward. A negative ρ tilts it downward. If ρ = 0 and the variances differ, the ellipse aligns with the coordinate axes.
Correlation does not identify a cause. Zero covariance also does not establish independence for arbitrary distributions. For example, let X be uniform on [−1, 1] and Y = X²: symmetry gives Cov(X,Y) = E[X³] = 0, yet knowing X determines Y.
Jointly Gaussian variables are a special case: zero cross-covariance implies independence. Arnab Maity's multivariate-normal notes state that property alongside the distribution's elliptical contours.
Measure distance in the shape of the distribution
Euclidean distance counts meters equally in every direction. Mahalanobis distance accounts for the covariance:
d² = (p − μ)ᵀΣ⁻¹(p − μ)
ellipse boundary: d² = q
The quantity d² is dimensionless. For a positive-definite Σ, a fixed positive q defines an ellipse centered on μ. NIST's Gaussian density formula depends on position through this quadratic expression, so this boundary also has constant density.
In the lab, μ = (0, 0). One way to undo its covariance is:
z₁ = x / σₓ
z₂ = (y / σᵧ − ρz₁) / √(1 − ρ²)
d² = z₁² + z₂²
These whitened coordinates transform the model into a standard bivariate Gaussian. The ellipse becomes a circle of radius √q. Whitening need not be a rotation alone; it also removes unequal scale and correlation.
Find the ellipse axes and angle
Write Σ = [[a, b], [b, d]]. Its two eigenvalues are:
λ₊, λ₋ = [a + d ± √((a − d)² + 4b²)] / 2
major semiaxis = √(qλ₊)
minor semiaxis = √(qλ₋)
The eigenvalues are variances, with units of m². Taking their square roots supplies lengths in meters. A semiaxis runs from the center to the boundary, so the full axis is twice that length.
For unequal eigenvalues, the major-axis angle is θ = ½ atan2(2b, a − d), measured counterclockwise from positive x. An ellipse axis has no arrow: adding 180° describes the same direction. If a = d and b = 0, the contour is a circle and no unique major-axis angle exists.
Choose a probability contour
For a bivariate Gaussian with known μ and positive-definite Σ, d² follows a chi-square distribution with two degrees of freedom. Maity's notes give this connection, and NIST describes the chi-square distribution.
In two dimensions, the mass inside radius r has a simple expression. Integrating the standard Gaussian in polar coordinates gives:
P(d² ≤ q) = 1 − exp(−q/2)
q = −2 ln(1 − p)
At radius 1, q = 1 and the enclosed mass is 39.346934%. The familiar one-dimensional interval μ ± σ contains about 68.27% of a normal distribution; a two-dimensional ellipse uses a different probability calculation.
For 95% mass, q = −2 ln(0.05) = 5.991465 and √q = 2.447747. Gaussian tails continue outside this ellipse. A covariance contour cannot certify a collision-free robot position or a deterministic worst-case error.
Calculate one uncertainty ellipse
Set σₓ = 1 m, σᵧ = 0.5 m, ρ = 0.6. Then:
Σ = [[1, 0.3], [0.3, 0.25]] m²
det Σ = 1 × 0.25 − 0.3² = 0.16 m⁴
The eigenvalue gap is √(0.75² + 4 × 0.3²) = 0.960469 m². The eigenvalues are 1.105234 and 0.144766 m², and θ = ½ atan2(0.6, 0.75) = 19.329904°.
Multiplying their square roots by 2.447747 gives the 95% semiaxes: 2.573319 and 0.931321 m. The ellipse's area is π times their product, or 7.529096 m².
As a separate check, the point (1, 0.3) m whitens to (1, 0). Its squared Mahalanobis distance is exactly 1, so it lies on the unit-radius contour and inside the 95% contour.
Change the covariance in the lab
Choose Negative correlation to reverse the tilt. The eigenvalues and semiaxis lengths stay the same because changing the sign of b leaves b² unchanged. Choose Circular distribution to make both model variances equal to 1 m² and model cross-covariance equal to zero.
Switch the contour to Mahalanobis radius 1. The distribution covariance stays fixed, while the semiaxes shrink to 1.051301 and 0.380481 m for the default shape. The selected probability falls to 39.346934%.
The lab uses 64 fixed, seeded standard-normal draws and transforms them by x = σₓz₁ and y = σᵧ(ρz₁ + √(1 − ρ²)z₂). Reusing those normalized draws isolates shape changes: adjusting covariance preserves which points fall inside a selected contour. The second plot makes that relationship visible.
Separate samples, distributions, and estimated means
The model specifies Σ. A finite set of n observations produces a sample covariance using its sample mean p̄:
S = [1 / (n − 1)] Σᵢ (pᵢ − p̄)(pᵢ − p̄)ᵀ
For the default 64 dots, S has entries 0.972947, 0.249155, 0.214700 m² in its upper triangle. The sample also puts 59 of 64 points, or 92.1875%, inside the model's 95% ellipse. A finite sample need not reproduce population covariance or population proportions exactly.
The divisor n − 1 makes S unbiased for population covariance under independent, identically distributed sampling with finite second moments. The plotted dots come from a seeded pseudo-random generator for repeatability. They illustrate sampling variation; they do not validate a robot's uncertainty model.
A confidence region for an unknown mean answers a different statistical question. Under independent Gaussian sampling with known Σ, the sample mean has covariance Σ/n; a 95% confidence-region procedure centered on that mean uses semiaxes smaller by √n. Estimating Σ from the same data changes the finite-sample calibration, so simply relabeling the displayed ellipse as a confidence region would be incorrect.
Reproduce the geometry in Python
This standard-library calculation checks the matrix, axes, probability, and one Mahalanobis distance. The final line uses a separate three-point dataset to verify sample covariance by hand.
from math import atan2, degrees, exp, hypot, log, pi, sqrt
sx, sy, rho = 1.0, 0.5, 0.6
xx, xy, yy = sx*sx, rho*sx*sy, sy*sy
q = -2 * log(0.05)
gap = hypot(xx - yy, 2*xy)
large, small = (xx + yy + gap)/2, (xx + yy - gap)/2
major, minor = sqrt(q*large), sqrt(q*small)
angle = degrees(atan2(2*xy, xx - yy)/2)
print(f"Covariance: [[{xx:.6f}, {xy:.6f}], [{xy:.6f}, {yy:.6f}]]")
print(f"Eigenvalues: {large:.6f}, {small:.6f} m^2")
print(f"Angle: {angle:.6f} deg")
print(f"95% semiaxes: {major:.6f}, {minor:.6f} m")
print(f"95% area: {pi*major*minor:.6f} m^2")
print(f"Unit-radius mass: {100*(1-exp(-0.5)):.6f}%")
x, y = 1.0, 0.3
# Direct inverse-matrix quadratic form, independent of whitening.
d2 = (yy*x*x - 2*xy*x*y + xx*y*y)/(xx*yy - xy*xy)
print(f"Distance squared at (1, 0.3): {d2:.6f}")
points = [(-1, -2), (0, 0), (1, 2)]
mx = sum(p[0] for p in points)/len(points)
my = sum(p[1] for p in points)/len(points)
cov_xy = sum((x-mx)*(y-my) for x, y in points)/(len(points)-1)
print(f"Three-point sample covariance xy: {cov_xy:.6f} m^2")
Expected output:
Covariance: [[1.000000, 0.300000], [0.300000, 0.250000]]
Eigenvalues: 1.105234, 0.144766 m^2
Angle: 19.329904 deg
95% semiaxes: 2.573319, 0.931321 m
95% area: 7.529096 m^2
Unit-radius mass: 39.346934%
Distance squared at (1, 0.3): 1.000000
Three-point sample covariance xy: 2.000000 m^2
Try two covariance checks
Exercise 1. For the three points (−1, −2), (0, 0), and (1, 2) m, calculate the full sample covariance. Is it invertible? Explain what the point geometry tells you.
Check the three-point covariance
The mean is (0, 0). Dividing the centered sums by n − 1 = 2 gives S = [[1, 2], [2, 4]] m². Its determinant is 4 − 4 = 0, so it has no inverse. Every point lies on y = 2x; the direction perpendicular to that line has zero sample variance. A covariance contour collapses along that direction, outside the positive-definite domain used by the lab.
Exercise 2. Suppose 64 independent Gaussian observations have the known default covariance. Compare the 95% distribution-contour semiaxes with the semiaxes of a 95% confidence region for their unknown mean. Which covariance belongs to the sample mean?
Check spread versus mean uncertainty
The distribution semiaxes are 2.573319 and 0.931321 m. The sample mean has covariance Σ/64, so its region has semiaxes smaller by √64 = 8: 0.321665 and 0.116415 m. Center that confidence region on the observed sample mean. Across repeated independent samples, this known-covariance Gaussian procedure covers the fixed population mean 95% of the time; it does not shrink the spread of individual observations.
Sources and further study
- NIST, The Multivariate Normal Distribution: Gaussian density, covariance entries, and the correlation coefficient.
- Arnab Maity, North Carolina State University, Multivariate Normal Distribution: Mahalanobis distance, Gaussian independence, and the distribution of a sample mean.
- NIST, Chi-Square Distribution: the distribution used to choose a Gaussian probability contour.
Follow eigenvalues to inspect the directions behind the shape, or continue to the Kalman filter to see an estimator propagate and update covariance.