Created
August 10, 2017 11:29
-
-
Save toinsson/5d52575e15fd8091fa3982a5fc0663ce to your computer and use it in GitHub Desktop.
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
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 | |
def compute_ellipse_parameters(points): | |
pos = points.mean(axis=0) | |
cov = np.cov(points, rowvar=False) | |
def eigsorted(cov): | |
vals, vecs = np.linalg.eigh(cov) | |
order = vals.argsort()[::-1] | |
return vals[order], vecs[:,order] | |
vals, vecs = eigsorted(cov) | |
theta = np.degrees(np.arctan2(*vecs[:,0][::-1])) | |
# Width and height are "full" widths, not radius | |
width, height = 2 * 2 * np.sqrt(vals) | |
return pos, width, height |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment