2013-10-11 2 views
6

~ 300k 데이터 포인트의 산점도를 생성하고 있으며 구조가 표시되지 않는 곳에서 너무 붐비고 있다는 문제가 있습니다. !분산 형 플롯의 밀도가 가장 높은 영역에 대한 윤곽 그리기

밀도가 가장 높은 부분에 대한 등고선 플롯을 생성하고 덜 밀도가 높은 영역을 데이터 포인트 scatter()과 함께 남기고 싶습니다.

각 데이터 포인트에 대해 가장 가까운 이웃 거리를 개별적으로 계산하려고 시도한 다음이 거리가 특정 값에 도달하면 등고선을 그려 채우고 그 다음에 채우기가 훨씬 큰 값) 그냥 산산조각을 내라.

나는 며칠 동안 노력했으나 실패했다. 나는이 경우 전통적인 등고선이 잘 작동하는지 확신하지 못한다.

코드를 제공 하겠지만 너무 지저분하고 문제를 혼동시킬 수 있습니다. 그리고 계산이 너무 집약적이어서 작동한다면 PC가 고장날 것입니다!

미리 감사드립니다.

p.s. 나는 해답을 찾아서 찾고있다! 나는 그것이 나타난 모든 결과조차도 가능하지 않다는 것을 확신합니다!

편집 :이 아이디어는 300k 샘플의 구조 내에서 특정 지점이 어디에 위치하는지 확인하는 것입니다. 여기 예제 플롯이 있는데, 내 포인트는 3 개의 diff로 분산되어 있습니다. 그림 물감. My scatter version of the data

나는 내 데이터에서 무작위로 1000 개의 데이터 포인트를 샘플링하여 텍스트 파일로 업로드하려고 시도 할 것이다. 건배 스태커. :)

편집 : 안녕하세요, 다음은 몇 가지 샘플 데이터입니다. 1000 행 - 두 개의 열 [X,Y] (또는 위 그림에서 [g-i,i]) 공백으로 구분됩니다. 다들 감사 해요! the data

+2

이 값이 붐비는 방법에 따라, 당신은 아마'산란 (X, Y, 알파 = 0.1) '또는 어떤 적합한 작은 값을 수행하여 어떤 구조를 애타게 할 수있다. 당신이 제안한 것을하기 위해, 나는 커널 밀도 추정치를 만들 것이다 ('scipy.stats.kde'를 보라). – chthonicdaemon

+3

2d 히스토그램을 사용하여 데이터를 표시하지 않는 이유는 무엇입니까? –

+1

@FriskyGrub 당신은 실제 데이터와 동일한 유형/모양/등의 무작위 데이터를 제공 할 수 있습니다. 처음부터 실제 데이터를 생성 한 복잡한 단계를 게시 할 필요는 없습니다. 우리가 당신에게 유용한 답변을 더 쉽게 제공합니다. – YXD

답변

0

4 년 후 나는 마침내 이것을 대답 할 수 있습니다! contains_points에서 matplotlib.path을 사용하여이 작업을 수행 할 수 있습니다.

astropy에서 Gaussian smoothing을 사용했습니다. 필요에 따라 생략하거나 대체 할 수 있습니다.

import matplotlib.colors as colors 
from matplotlib import path 
import numpy as np 
from matplotlib import pyplot as plt 
try: 
    from astropy.convolution import Gaussian2DKernel, convolve 
    astro_smooth = True 
except ImportError as IE: 
    astro_smooth = False 

np.random.seed(123) 
t = np.linspace(-1,1.2,2000) 
x = (t**2)+(0.3*np.random.randn(2000)) 
y = (t**5)+(0.5*np.random.randn(2000)) 

H, xedges, yedges = np.histogram2d(x,y, bins=(50,40)) 
xmesh, ymesh = np.meshgrid(xedges[:-1], yedges[:-1]) 

# Smooth the contours (if astropy is installed) 
if astro_smooth: 
    kernel = Gaussian2DKernel(stddev=1.) 
    H=convolve(H,kernel) 

fig,ax = plt.subplots(1, figsize=(7,6)) 
clevels = ax.contour(xmesh,ymesh,H.T,lw=.9,cmap='winter')#,zorder=90) 

# Identify points within contours 
p = clevels.collections[0].get_paths() 
inside = np.full_like(x,False,dtype=bool) 
for level in p: 
    inside |= level.contains_points(zip(*(x,y))) 

ax.plot(x[~inside],y[~inside],'kx') 
plt.show(block=False) 

enter image description here

1

당신은 NumPy와/scipy /하기 matplotlib 다양한 도구와이를 달성 할 수

  1. 빠른 검색을 위해 원래의 포인트 scipy.spatial.KDTree을 만듭니다.
  2. 사용 np.meshgrid은 어느 직사각형 빈 또는 plt.hexbin와 대상 밀도
  3. 빈 데이터 내에있는 모든 위치의 마스크를 만들 윤곽
  4. 사용 KDTree.query에게 원하는 해상도로 점의 격자를 만들 수 있습니다 .
  5. 비닝 된 데이터에서 윤곽을 플롯하지만 3 단계의 마스크를 사용하여 저밀도 영역을 필터링합니다.
  6. 마스크의 역함수를 사용하여 나머지 점을 plt.scatter에 지정합니다.
+0

나는 이것을 실제로 직접적으로 시도하지는 않았지만, 이것이 본질적으로 내가 한 일이다. 나는 hexbin 'heat plot'을 사용했다. 왜냐하면 순서 n^n -_-에서 등고선 물건의 계산 시간을 줄일 수 없었기 때문이다 ... 돌아갈만한 가치가 있을지도 모르고 재미있는 문제였다. – FriskyGrub

관련 문제