6

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

我想让该图为最密集的部分生成等高线图,并用scatter()数据点留下密度较低的区域。

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

我已经尝试并失败了几天,我不确定传统的等高线图在这种情况下是否有效。

我会提供代码,但它太乱了,可能只会混淆这个问题。而且它的计算量非常大,如果它确实有效,它可能只会让我的电脑崩溃!

谢谢大家!

ps 我一直在寻找和寻找答案!我相信它甚至不可能出现所有结果!

编辑:所以这样做的想法是查看某些特定点在 300k 样本的结构中的位置。这是一个示例图,我的观点分散在三个差异中。颜色。 我的数据分散版本

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

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

4

3 回答 3

3

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

我使用了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)

在此处输入图像描述

于 2017-08-01T10:22:41.883 回答
1

您可以使用各种 numpy/scipy/matplotlib 工具来实现这一点:

  1. 创建一个scipy.spatial.KDTree原始点以进行快速查找。
  2. 用于np.meshgrid以所需轮廓的分辨率创建点网格
  3. 用于KDTree.query创建目标密度内的所有位置的蒙版
  4. 使用矩形 bin 或plt.hexbin.
  5. 从分箱数据中绘制轮廓,但使用步骤 3 中的掩码过滤出较低密度区域。
  6. plt.scatter对其余点使用掩码的反转。
于 2013-10-29T19:58:56.403 回答
1

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

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)

在此处输入图像描述

(scatter_contour??在帮助下提供了很多文档,但基本上正如 kwargs 所建议的那样,histogram2d_args那些 args是由 scatter采用的numpy.histogram2d,并且是 scatter 采用的 args ,以及(or ) 采用的 那些plot_argsplt.plotcontour_argsplt.contourplt.contourf

最好的祝愿

克里斯

于 2019-10-25T19:08:02.170 回答