Python - 在等高线内集成2D核密度估计

时间:2017-01-10 23:57:00

标签: python contour kde

我想绘制核密度估计的等高线图,其中KDE集成在每个等高线图中。

举个例子,假设我计算了2D数据的KDE:

data = np.random.multivariate_normal((0, 0), [[1, 1], [2, 0.7]], 100)
x = data[:, 0]
y = data[:, 1]
xmin, xmax = min(x), max(x)
ymin, ymax = min(y), max(y)
xx, yy = np.mgrid[xmin:xmax:100j, ymin:ymax:100j]
positions = np.vstack([xx.ravel(), yy.ravel()])
values = np.vstack([x, y])
kernel = st.gaussian_kde(values)
f = np.reshape(kernel(positions).T, xx.shape)

我知道如何绘制KDE的等高线图。

fig = plt.figure()
ax = fig.gca()
ax.set_xlim(xmin, xmax)
ax.set_ylim(ymin, ymax)
cfset = ax.contourf(xx, yy, f, cmap='Blues')
cset = ax.contour(xx, yy, f, colors='k')
plt.show()

然而,此等值线图显示了每个填充区域内的概率密度。相反,我希望该图表示每个填充区域内的总概率。

1 个答案:

答案 0 :(得分:1)

请注意,只有您的轮廓是“单调的”时,以下内容才是正确的,即在轮廓线内部,您只能找到高于相应轮廓等级的像素值。另请注意,如果您的密度是多峰的,则将单独峰中的相应区域集中在一起。

如果这是真的/可以接受,可以通过按值排序像素来解决问题。

我不知道您的绘图程序选择其轮廓级别的哪种启发式方法,但假设您将它们存储(按升序排序,比如说)在一个名为“级别”的变量中,您可以尝试类似

的内容
ff = f.ravel()
order = np.argsort(ff)
fsorted = ff[order]
F = np.cumsum(fsorted)
# depending on how your density is normalised next line may be superfluous
# also note that this is only correct for equal bins
# and, finally, to be unimpeachably rigorous, this disregards the probability
# mass outside the field of view, so it calculates probability condtional
# on being in the field of view
F /= F[-1]
boundaries = fsorted.searchsorted(levels)
new_levels = F[boundaries]

现在,为了能够使用它,您的绘图程序必须允许您自由选择轮廓标签或至少选择放置轮廓的级别。在后一种情况下,假设有一个kwarg'水平'

# make a copy to avoid problems with in-place shuffling
# i.e. overwriting positions whose original values are still to be read out
F[order] = F.copy()
F.shape = f.shape
cset = ax.contour(xx, yy, F, levels=new_levels, colors='k')

我从您的一条评论中复制了以下内容,以使其更加明显

  

最后,如果想要在每个填充区域内确实具有概率,这是一个有效的解决方法:cb = fig.colorbar(cfset,ax = ax)values = cb.values.copy()values [1: ] - =值[: - 1] .copy()cb.set_ticklabels(values) - 劳拉