0

I'm trying to plot the confidence ellipse for uniformly distributed points. When plotting the ellipse and the scatter plot using Matplotlib, I find that a portion of the ellipse is clipped by the subplot. I tried implementing other solutions suggested here on SO, given here, here, here and here. but am not able to correct the displayed plot.

How do I change the size of this subplot in order to correctly and completely display the ellipse?

Code for generating ellipse: multidimensional confidence intervals

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.patches import Ellipse

def eigsorted(cov):
    vals, vecs = np.linalg.eigh(cov)
    order = vals.argsort()[::-1]
    return vals[order], vecs[:,order]

nstd = 2

fig = plt.figure(1, figsize=(12, 5))
#ax = plt.subplots(111)
ax = fig.add_subplot(111, aspect='equal')
test1 = np.random.uniform(40, 60, 1000)
test2 = np.random.uniform(100, 120, 1000)
cov = np.cov(test1, test2)
vals, vecs = eigsorted(cov)
theta = np.degrees(np.arctan2(*vecs[:,0][::-1]))
w, h = 2 * nstd * np.sqrt(vals)
ell = Ellipse(xy=(np.mean(test1), np.mean(test2)),
              width=w, height=h,
              angle=theta, color='black')
ell.set_facecolor('none')
ax.add_artist(ell)
plt.scatter(test1, test2)
plt.show()
surajr
  • 85
  • 1
  • 8

1 Answers1

0

As @ImportanceOfBeingEarnest rightly commented, a patch needed to be added for displaying the ellipse correctly. Updating the code below for future reference of others.

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.patches import Ellipse

def eigsorted(cov):
    vals, vecs = np.linalg.eigh(cov)
    order = vals.argsort()[::-1]
    return vals[order], vecs[:,order]

nstd = 2

fig = plt.figure(1, figsize=(12, 5))
#ax = plt.subplots(111)
ax = fig.add_subplot(111, aspect='equal')
test1 = np.random.uniform(40, 60, 1000)
test2 = np.random.uniform(100, 120, 1000)
cov = np.cov(test1, test2)
vals, vecs = eigsorted(cov)
theta = np.degrees(np.arctan2(*vecs[:,0][::-1]))
w, h = 2 * nstd * np.sqrt(vals)
ell = Ellipse(xy=(np.mean(test1), np.mean(test2)),
              width=w, height=h,
              angle=theta, color='black')
ell.set_facecolor('none')

#Corrected code for displaying ellipse correctly
ax.add_patch(ell)

plt.scatter(test1, test2)
plt.show()
surajr
  • 85
  • 1
  • 8