如何在matplotlib 3-D散点图上表示密度信息

时间:2018-12-18 03:59:56

标签: python-3.x matplotlib data-visualization mplot3d scatter3d

我试图将图像中的r,g,b通道绘制为3-D散点图。

当我有黑白图像时,这很好用,因为我得到了一个散点图,在散点图的两端只有两个不同的簇。

但是对于彩色图像,散点图在视觉上没有多大意义,因为存在r,g,b值,它们对应于图像颜色空间中的许多点。

所以我最终得到了如下图所示的图像-

3-D scatter plot without density information

我想实现的是以某种方式表示密度信息。例如,如果对应于(255,255,255)的点数为1000,而对应于(0,0,0)的点数仅为500,则我想要(255,255,255)为深红色而(0,0,0)为黄色/橙色

如何在matplotlib中实现这一目标?我也可以使用某种气泡效果,其中(255,255,255)表示为比(0,0,0)大的气泡,尽管我感觉编码为颜色信息的密度信息在视觉上会更具吸引力

1 个答案:

答案 0 :(得分:4)

这里是使用高斯KDE的尝试。它仍然远非完美,其结果很大程度上取决于估计参数(bw_method)。也许有一种更简单的方法,也许是使用np.unique来获取每种独特颜色的频率。

该想法是将颜色密度分布估计为多元高斯混合,并将其用作散点图的颜色图。

对于任何严重的问题,它都有点慢,但是我认为如果图像足够小,效果会很好。也许某些基于FFT +卷积的估计方法可能会更快。

让我们看一些代码。没什么好想的:它以gaussian_kde喜欢的方式展平并重塑图像数据,并返回RGB和密度分量。您可以与bw_method一起玩,看看结果如何变化,得到的密度越大,密度越大。

from scipy.stats import gaussian_kde

def img_to_rgbk(img, bw=0.1):
    rgb = img.reshape(-1, 3).T
    k = gaussian_kde(rgb, bw_method=bw)(rgb)
    r, g, b = rgb

    return r, g, b, k

以下是带有玩具图片的结果

img = chelsea()[100:200, 100:200]

fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')

r, g, b, k = img_to_rgbk(img, bw=0.5)
ax.scatter(r, g, b, c=k, alpha=0.2)

通知c=k用于将地图标记的颜色设置为浓度信息,alpha可以使云层看到一点。

切尔西

Chelsea the cat color density

随机颜色

random uniform color density

渐变

请注意,您会看到错误的带宽选择会产生误导。足够小的bw_method应该基本上每列显示一种颜色,并沿行重复。因此,每个点都应具有相同的颜色(并且具有正确的带宽)。 spectral colormap density

渐变+噪波

这里具有更好的带宽和一些噪音以散布颜色。请注意,白色区域周围的密度较大,在该区域中,无噪声图中的不连续点变为密度最大值。 spectral + noise = fun