Изменение размера участка для правильного отображения эллипса - PullRequest
0 голосов
/ 08 октября 2019

Я пытаюсь построить доверительный эллипс для равномерно распределенных точек. При построении эллипса и графика рассеяния с использованием Matplotlib я обнаружил, что часть эллипса обрезана по вспомогательному графику. Я попытался реализовать другие решения, предложенные здесь для SO, учитывая здесь , здесь , здесь и здесь . но я не могу исправить отображаемый сюжет.

Как изменить размер этого вспомогательного участка, чтобы правильно и полностью отобразить эллипс?

Код для создания эллипса: многомерные доверительные интервалы

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()

1 Ответ

0 голосов
/ 08 октября 2019

Как правильно заметил @ImportanceOfBeingEarnest, для корректного отображения эллипса необходимо добавить патч. Обновление кода ниже для дальнейшего использования.

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()
...