Kontury Scatterplot W Matplotlib

[[0]}mam ogromny scatterplot (~100,000 punktów), który generuję w matplotlib. Każdy punkt ma miejsce w tej przestrzeni x/y i chciałbym wygenerować kontury zawierające pewne percentyle całkowitej liczby punktów.

Czy w matplotlib jest funkcja, która to zrobi? Przyjrzałem się contour (), ale musiałbym napisać własną funkcję, aby działać w ten sposób.

Dzięki!

Author: Joe Kington, 2013-10-16

2 answers

Zasadniczo, chcesz oszacować gęstość jakiegoś rodzaju. Można to zrobić na wiele sposobów:

  1. Użyj histogramu 2D jakiegoś rodzaju (np. matplotlib.pyplot.hist2d lub matplotlib.pyplot.hexbin) (Możesz również wyświetlić wyniki jako kontury-po prostu użyj numpy.histogram2d, a następnie kontur tablicy wynikowej.)

  2. Wykonaj oszacowanie gęstości jądra (KDE) i konturuj wyniki. KDE jest zasadniczo wygładzonym histogramem. Zamiast punktu wpadającego do określonego pojemnika, dodaje wagę do otaczających pojemników (zwykle w kształcie Gaussa "krzywa dzwonka").

Korzystanie z histogramu 2D jest proste i łatwe do zrozumienia, ale funddemently daje "blokowe" wyniki.

Są pewne zmarszczki do zrobienia drugiego "poprawnie" (tzn. nie ma jednego poprawnego sposobu). Nie będę tu wchodzić w szczegóły, ale jeśli chcesz statystycznie zinterpretować wyniki, musisz poczytać o tym (szczególnie o wyborze pasma).

W każdym razie, oto przykład różnic. I ' m każdy z nich będzie rysowany podobnie, więc nie będę używał konturów, ale równie łatwo można narysować histogram 2D lub Gaussian KDE za pomocą wykresu konturów:

import numpy as np
import matplotlib.pyplot as plt
from scipy.stats import kde

np.random.seed(1977)

# Generate 200 correlated x,y points
data = np.random.multivariate_normal([0, 0], [[1, 0.5], [0.5, 3]], 200)
x, y = data.T

nbins = 20

fig, axes = plt.subplots(ncols=2, nrows=2, sharex=True, sharey=True)

axes[0, 0].set_title('Scatterplot')
axes[0, 0].plot(x, y, 'ko')

axes[0, 1].set_title('Hexbin plot')
axes[0, 1].hexbin(x, y, gridsize=nbins)

axes[1, 0].set_title('2D Histogram')
axes[1, 0].hist2d(x, y, bins=nbins)

# Evaluate a gaussian kde on a regular grid of nbins x nbins over data extents
k = kde.gaussian_kde(data.T)
xi, yi = np.mgrid[x.min():x.max():nbins*1j, y.min():y.max():nbins*1j]
zi = k(np.vstack([xi.flatten(), yi.flatten()]))

axes[1, 1].set_title('Gaussian KDE')
axes[1, 1].pcolormesh(xi, yi, zi.reshape(xi.shape))

fig.tight_layout()
plt.show()

Tutaj wpisz opis obrazka

Jedno zastrzeżenie: przy bardzo dużej liczbie punktów, scipy.stats.gaussian_kde będzie bardzo wolno. Jest to dość łatwe do przyspieszenia poprzez przybliżenie--wystarczy wziąć histogram 2D i rozmyć go z guassian filtrem odpowiedniego promienia i kowariancji. Mogę podać przykład, jeśli chcesz.

Jeszcze jedno zastrzeżenie: jeśli jesteś robiąc to w nie-kartezjańskim układzie współrzędnych, żadna z tych metod nie ma zastosowania ! Uzyskanie oszacowania gęstości na kulistej skorupie jest nieco bardziej skomplikowane.

 41
Author: Joe Kington,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-10-15 21:16:53

Mam to samo pytanie. Jeśli chcesz rysować kontury, które zawierają pewną część punktów, możesz użyć następującego algorytmu:

Tworzenie histogramu 2d

h2, xedges, yedges = np.histogram2d(X, Y, bibs = [30, 30])

H2 jest teraz macierzą 2d zawierającą liczby całkowite, która jest liczbą punktów w pewnym prostokącie

hravel = np.sort(np.ravel(h2))[-1] #all possible cases for rectangles 
hcumsum = np.sumsum(hravel)

Brzydki hack,

Dajmy dla każdego punktu w macierzy H2 2D skumulowaną liczbę punktów dla prostokąta, które zawierają liczbę punktów równą lub większą do tej, którą analizujemy obecnie.

hunique = np.unique(hravel)

hsum = np.sum(h2)

for h in hunique:
    h2[h2 == h] = hcumsum[np.argwhere(hravel == h)[-1]]/hsum

Teraz fabuła kontur dla h2, będzie to kontur zawierający pewną ilość wszystkich punktów

 2
Author: andrey,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-01-28 10:01:39