2014-11-02 98 views
13

当处理重叠的高密度散射或不同颜色的线条图时,可以方便地实施添加剂混合方案,其中每个标记的RGB颜色相加在一起以产生画布中的最终颜色。这是2D和3D渲染引擎中的常见操作。是否可以使用matplotlib进行添加剂混合?

但是,在Matplotlib中,我只找到了对alpha/opacity混合的支持。是否有任何迂回的做法,或者我坚持渲染位图,然后将它们混合到一些绘图程序中?

编辑:下面是一些示例代码和手动解决方案。

这将产生两个部分重叠的随机分布:

x1 = randn(1000) 
y1 = randn(1000) 
x2 = randn(1000) * 5 
y2 = randn(1000) 
scatter(x1,y1,c='b',edgecolors='none') 
scatter(x2,y2,c='r',edgecolors='none') 

这将产生matplotlib如下: scatter - no blend

正如你所看到的,是由闭塞一些重叠的蓝点红点,我们希望看到他们。通过使用alpha /阻在matplotlib混合,你可以这样做:

scatter(x1,y1,c='b',edgecolors='none',alpha=0.5) 
scatter(x2,y2,c='r',edgecolors='none',alpha=0.5) 

将产生如下:

scatter - alpha blend (0.5)

但我真正想要的是以下几点:

scatter - additive blend

我可以通过将每个绘图独立渲染到位图来手动完成:

xlim = plt.xlim() 
ylim = plt.ylim() 
scatter(x1,y1,c='b',edgecolors='none') 
plt.xlim(xlim) 
plt.ylim(ylim) 
scatter(x2,y2,c='r',edgecolors='none') 
plt.xlim(xlim) 
plt.ylim(ylim) 
plt.savefig(r'scatter_blue.png',transparent=True) 
plt.savefig(r'scatter_red.png',transparent=True) 

这给了我下面的图片:

scatter - red/blue channels

你可以做的,然后是加载它们在Paint.NET/PhotoShop/gimp独立层,只是添加剂混合物他们。

现在的理想将是能够在Matplotlib中以编程方式执行此操作,因为我将处理数百个这些!

+0

最简单的做法可能是制作二维直方图。请向我们展示一些示例代码和数据以使我们开始。 – 2014-11-02 17:58:55

+0

谢谢,只是添加了一些示例代码和手动解决方案的步骤。 – glopes 2014-11-02 18:31:38

+0

谢谢,现在更好的问题,会看到我能做些什么。 – 2014-11-02 19:13:14

回答

7

如果你只需要一个形象的结果,你可以得到画布缓冲区作为numpy的数组,然后做混合,这里有一个例子:

from matplotlib import pyplot as plt 
import numpy as np 

fig, ax = plt.subplots() 
ax.scatter(x1,y1,c='b',edgecolors='none') 
ax.set_xlim(-4, 4) 
ax.set_ylim(-4, 4) 
ax.patch.set_facecolor("none") 
ax.patch.set_edgecolor("none") 
fig.canvas.draw() 

w, h = fig.canvas.get_width_height() 
img = np.frombuffer(fig.canvas.buffer_rgba(), np.uint8).reshape(h, w, -1).copy() 

ax.clear() 
ax.scatter(x2,y2,c='r',edgecolors='none') 
ax.set_xlim(-4, 4) 
ax.set_ylim(-4, 4) 
ax.patch.set_facecolor("none") 
ax.patch.set_edgecolor("none") 
fig.canvas.draw() 

img2 = np.frombuffer(fig.canvas.buffer_rgba(), np.uint8).reshape(h, w, -1).copy() 

img[img[:, :, -1] == 0] = 0 
img2[img2[:, :, -1] == 0] = 0 

fig.clf() 

plt.imshow(np.maximum(img, img2)) 
plt.subplots_adjust(0, 0, 1, 1) 
plt.axis("off") 
plt.show() 

结果:

enter image description here

+0

我实际上只是在你的答案出现时检查buffer_rgba()函数。是的,我认为这是Matplotlib现在可以做的最好的。出于某种原因,在我的Matplotlib版本中,最终的结果并不尽如人意(透明度被搞砸了),但我确信只要稍微调整一下,我就可以立即开始工作。谢谢! – glopes 2014-11-03 11:15:35

相关问题