We draw a confidence ellipse by calling the following function that calculates its x and y coordinates:
import numpy as np
def get_ellipse(center: np.ndarray, cova: np.ndarray, nsigma: int = 1, npoints: int = 1000) -> np.ndarray:
"""
Return the coordinates of a covariance ellipse.
Args:
center (np.ndarray): The center of the ellipse.
cova (np.ndarray): The covariance matrix.
nsigma (int, optional): The number of standard deviations for the ellipse. Defaults to 1.
npoints (int, optional): The number of points to generate on the ellipse. Defaults to 1000.
Returns:
np.ndarray: The coordinates of the ellipse.
"""
cholesky_l = np.linalg.cholesky(cova)
t = np.linspace(0, 2 * np.pi, npoints)
circle = np.column_stack([np.cos(t), np.sin(t)])
ellipse = nsigma * circle @ cholesky_l.T + center
return ellipse.T
The function, proposed by one of my teaching assistants, uses the Cholesky decomposition. The confidence ellipses can be plotted with the following code:
import matplotlib.pyplot as plt
x = [5,7,11,15,16,17,18]
y = [8, 5, 8, 9, 17, 18, 25]
mean = np.mean([x, y])
cov = np.cov(x, y, ddof=1)
fig, ax = plt.subplots()
ax.set_xlabel("x")
ax.set_ylabel("y")
ax.scatter(x,y)
x_1sigma, y_1sigma = get_ellipse(mean, cov, nsigma=1)
ax.plot(x_1sigma, y_1sigma, label='$1\sigma$')
x_2sigma, y_2sigma = get_ellipse(mean, cov, nsigma=2)
ax.plot(x_2sigma, y_2sigma, label='$2\sigma$')
x_3sigma, y_3sigma = get_ellipse(mean, cov, nsigma=3)
ax.plot(x_3sigma, y_3sigma, label='$3\sigma$')
ax.legend()
We prefer using ddof=1 in numpy.cov to get an unbiased estimator of the covariance matrix.
Plot of the 1, 2, and 3σ covariance ellipses
type=meanis specifying.) My answer that @SaulloCastro linked to shows a confidence ellipse for the entire population (in other words, the area that another sample from the population should fall inside, identical totype=predictedin SAS). Jamie's answer uses this method as well.