Python imshow如何处理带有M x N x 4输入的alpha通道?

Python imshow如何处理带有M x N x 4输入的alpha通道?,python,matplotlib,Python,Matplotlib,生长激素问题 我正在使用matplotlib中的imshow函数来可视化一些数据。我有两个数组,A和B,大小相同。我想使用彩色贴图来显示a中的标量值,我想使用alpha通道来显示B中的标量值。换句话说,如果a和B中给定坐标处的值都很大,那么绘图中的像素将是亮绿色和不透明的。如果它在A中较大而不是B中,那么它将是亮绿色,但大部分是透明的。如果它在B而不是A中很大,那么它将是不透明的,但是白色的 但是,生成的图像并不是我所期望的。我的输入数据称为d,它是将a数组与matplotlib colorm

生长激素问题


我正在使用matplotlib中的
imshow
函数来可视化一些数据。我有两个数组,A和B,大小相同。我想使用彩色贴图来显示a中的标量值,我想使用alpha通道来显示B中的标量值。换句话说,如果a和B中给定坐标处的值都很大,那么绘图中的像素将是亮绿色和不透明的。如果它在A中较大而不是B中,那么它将是亮绿色,但大部分是透明的。如果它在B而不是A中很大,那么它将是不透明的,但是白色的

但是,生成的图像并不是我所期望的。我的输入数据称为
d
,它是将a数组与matplotlib colormap(即
mpl.cm.BuGn(a)
)和B数组映射后产生的RGB值的组合

这里我将绘制完整的图像(我想要实际使用的)、RGB图像(A,用
BuGn
映射)和alpha提供数组(B,用灰度彩色映射)

我对完整图像中的斑点灰色垃圾从何而来感到困惑,因为在colormap中没有这些颜色的值。为了更显著地显示这种效果,我可以更改颜色贴图的边界,使其远离数据的极端,然后重新绘制:

我不明白为什么带有较大alpha值的白色像素显示为灰色。不透明的白色应该仍然是白色

请注意,此行为与我绘制RGB组件数组并使用
alpha
kwarg降低透明度不同,即
ax2.imshow(d[…,:-1],alpha=.3)


我的第一个答案完全错了,下面是我的新尝试

达维伦的上述评论准确地再现了这一问题

import numpy as np
import matplotlib.pyplot as plt

d = np.ones((100, 100, 4), dtype=np.uint8)*255
d[:, :, 3] = np.linspace(0, 255, num=100)
plt.imshow(d, interpolation='none')
plt.show()
产生:

您可能希望白色背景上带有可变alpha的白色图像是完全白色的。“直线”阿尔法就是这样

看起来matlplotlib的图形后端显示的图像采用“预乘”alpha,这意味着alpha会影响图像的颜色。这可以解释上面的图像

当显示为(1.0,1.0,1.0,0.5)的像素时,其颜色首先乘以其alpha通道,因此它们显示为(0.5,0.5,0.5,0.5)灰色

右边的像素是不透明和白色的,因此它们看起来是白色的。左侧的像素显示为黑色和透明,因此它们与背景色(白色)相同


中间的像素是灰色的,因为它们既不显示白色也不显示透明。

< P>由古老的圆珠笔修正的答案似乎是合理的。从那个邮件列表帖子中,似乎没有仔细考虑alpha值的处理。此外,从原始帖子中的示例来看,
imshow
中的
alpha
arg的合成方式似乎与RGBA数据中提供的alpha数字不同

为了解决混合Agg正在做的任何事情,可以避免alpha并手动进行合成

A = np.tile(np.linspace(0, 1, num=100), (100, 1))  # gradient
B = A.T
d = plt.cm.BuGn(A)
d[..., -1] = B

composite = (d[..., :-1] * d[..., -1].reshape(100, 100, 1) +
    (1 - d[..., -1]).reshape(100, 100, 1))

fig, axes = plt.subplots(1, 2)
axes[0].imshow(d)
axes[1].imshow(composite)


我确信有更好的方法来进行整形,但这不是问题所在。

我认为这不太正确,因为如果你做
ax.imshow(d[…,:-1]],alpha=0.3),你看不到同样的东西。
。我编辑了这个问题,以显示结果及其与完整图像的对比。@mwaskom:是的,您看到这种行为是因为matplotlib中的轴背景是白色的。使用fig.axes[0]将轴颜色更改为黑色。设置_axis_bgcolor(“黑色”),您就会明白我的意思。我不知道这与上面两个图之间的差异有什么关系。axis的背景都是白色的。我这里没有做任何向下投票,但我很确定你用粗体表示的说法是错误的。在我使用过的每个成像程序中,alpha为0的白色像素都是透明的,而不是黑色的。背景是白色的。所以这个解释更有意义,但它不能完全解释为什么
ax.imshow(…,alpha=.3)
看起来不错,但在图像中添加alpha通道却不行。预乘行为是可配置的吗?奇怪。也可以使用简单的渐变进行复制,无需彩色贴图:
d=np.ones((100100,4));d[…,-1]=np.linspace(0,1,num=100);plt.imshow(d)
@DanAllan这只是因为matplotlib中默认的白色画布颜色。这不是我使用的任何成像软件中处理透明度的方式。@DanAllan可能是预乘?另见,这回答了提出的问题;不幸的是,我实际上需要alpha,因为我想在B低的区域(a大脑)看到一个背景图像。但这告诉我,我必须采取不同的策略。我想你可以用我在这里隐式合成1数组的方法合成图像。
A = np.tile(np.linspace(0, 1, num=100), (100, 1))  # gradient
B = A.T
d = plt.cm.BuGn(A)
d[..., -1] = B

composite = (d[..., :-1] * d[..., -1].reshape(100, 100, 1) +
    (1 - d[..., -1]).reshape(100, 100, 1))

fig, axes = plt.subplots(1, 2)
axes[0].imshow(d)
axes[1].imshow(composite)