绘制散点图最密集区域的轮廓

时间:2013-10-11 06:52:26

标签: python numpy matplotlib scipy contour

我正在生成一个约300k数据点的散点图,并且我遇到的问题是,在某些地方过于拥挤,没有任何结构可见 - 所以我有一个想法!

我希望图表为最密集的部分生成等高线图,并使密度较低的区域留下scatter()个数据点。

所以我试图为每个数据点单独计算最近邻距离,然后当该距离达到特定值时,绘制轮廓并填充它,然后当它达到更大的值(密度更小)时只做分散......

我一直在尝试和失败几天,我不确定传统的轮廓图在这种情况下是否有效。

我会提供代码,但它太乱了,可能只是混淆了这个问题。它的计算密集程度很高,如果确实有效,它可能会让我的电脑崩溃!

提前谢谢大家!

P.S。我一直在寻找答案!我确信它出现的所有结果都不可能!

编辑:所以这个想法是看看300k样本结构中某些特定点的位置。这是一个示例情节,我的点分散在三个差异中。颜色。 My scatter version of the data

我将尝试从我的数据中随机抽取1000个数据点并将其作为文本文件上传。 干杯堆叠器。 :)

编辑:嘿, 以下是一些示例数据1000行 - 只有两列[X,Y](或上图中的[g-i,i])空格分隔。谢谢你们! the data

3 个答案:

答案 0 :(得分:1)

您可以使用各种numpy / scipy / matplotlib工具实现此目的:

  1. 创建原始点的scipy.spatial.KDTree以便快速查找。
  2. 使用np.meshgrid以您想要轮廓
  3. 的分辨率创建点网格
  4. 使用KDTree.query创建目标密度
  5. 内所有位置的蒙版
  6. 使用矩形框或plt.hexbin对数据进行分区。
  7. 从分箱数据中绘制轮廓,但使用步骤3中的遮罩滤除较低密度区域。
  8. 使用遮罩的反转来plt.scatter剩下的点。

答案 1 :(得分:0)

4年后,我终于可以回答这个了! 这可以使用contains_points中的matplotlib.path来完成。

我使用了来自astropy的高斯平滑,可以根据需要省略或替换。

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

答案 2 :(得分:0)

也许有人(例如我)会偶然发现互联网上寻找答案。 @FriskyGrub,我喜欢您的平滑方法。 AstroML库中有一个解决方案,例如https://www.astroml.org/book_figures/chapter1/fig_S82_scatter_contour.html#book-fig-chapter1-fig-s82-scatter-contour。我不确定如何在代码中设置阈值(在阈值之上将阈值包括在轮廓中而不是分散),但是我设法通过:p再现了与您相似的结果

import matplotlib.pyplot as plt
from astroML.plotting import scatter_contour
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))
fig,ax = plt.subplots(1,1,figsize=(6,6))
scatter_contour(x,y, threshold=15, log_counts=True, ax=ax,
            histogram2d_args=dict(bins=15),
            plot_args=dict(marker='+', linestyle='none', color='black',
                          markersize=5),
            contour_args=dict(cmap='winter',),
           filled_contour=False)

enter image description here

scatter_contour??带来了很多文档的帮助,但基本上如kwargs所建议,histogram2d_argsnumpy.histogram2d所使用的args,而plot_args是分散plt.plotcontour_argsplt.contour(或plt.contourf)分散

最美好的祝愿

克里斯

相关问题