Created
April 5, 2019 08:27
-
-
Save AngelBerihuete/e10714d3452115cc8d934ce9b9c5f0ca to your computer and use it in GitHub Desktop.
From https://github.com/joferkington/oost_paper_code/blob/master/error_ellipse.py by @joferkington
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import numpy as np | |
import matplotlib.pyplot as plt | |
from matplotlib.patches import Ellipse | |
def plot_point_cov(points, nstd=2, ax=None, **kwargs): | |
""" | |
Plots an `nstd` sigma ellipse based on the mean and covariance of a point | |
"cloud" (points, an Nx2 array). | |
Parameters | |
---------- | |
points : An Nx2 array of the data points. | |
nstd : The radius of the ellipse in numbers of standard deviations. | |
Defaults to 2 standard deviations. | |
ax : The axis that the ellipse will be plotted on. Defaults to the | |
current axis. | |
Additional keyword arguments are pass on to the ellipse patch. | |
Returns | |
------- | |
A matplotlib ellipse artist | |
""" | |
pos = points.mean(axis=0) | |
cov = np.cov(points, rowvar=False) | |
return plot_cov_ellipse(cov, pos, nstd, ax, **kwargs) | |
def plot_cov_ellipse(cov, pos, nstd=2, ax=None, **kwargs): | |
""" | |
Plots an `nstd` sigma error ellipse based on the specified covariance | |
matrix (`cov`). Additional keyword arguments are passed on to the | |
ellipse patch artist. | |
Parameters | |
---------- | |
cov : The 2x2 covariance matrix to base the ellipse on | |
pos : The location of the center of the ellipse. Expects a 2-element | |
sequence of [x0, y0]. | |
nstd : The radius of the ellipse in numbers of standard deviations. | |
Defaults to 2 standard deviations. | |
ax : The axis that the ellipse will be plotted on. Defaults to the | |
current axis. | |
Additional keyword arguments are pass on to the ellipse patch. | |
Returns | |
------- | |
A matplotlib ellipse artist | |
""" | |
def eigsorted(cov): | |
vals, vecs = np.linalg.eigh(cov) | |
order = vals.argsort()[::-1] | |
return vals[order], vecs[:,order] | |
if ax is None: | |
ax = plt.gca() | |
vals, vecs = eigsorted(cov) | |
theta = np.degrees(np.arctan2(*vecs[:,0][::-1])) | |
# Width and height are "full" widths, not radius | |
width, height = 2 * nstd * np.sqrt(vals) | |
ellip = Ellipse(xy=pos, width=width, height=height, angle=theta, **kwargs) | |
ax.add_artist(ellip) | |
return ellip | |
if __name__ == '__main__': | |
#-- Example usage ----------------------- | |
# Generate some random, correlated data | |
points = np.random.multivariate_normal( | |
mean=(1,1), cov=[[0.4, 9],[9, 10]], size=1000 | |
) | |
# Plot the raw points... | |
x, y = points.T | |
plt.plot(x, y, 'ro') | |
# Plot a transparent 3 standard deviation covariance ellipse | |
plot_point_cov(points, nstd=3, alpha=0.5, color='green') | |
plt.show() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment