GH issue #3343
I am using the imshow
function in matplotlib to visualize some data. What I have are two arrays, A and B, that are the same size. I would like to use a colormap to show scalar values in A, and I would like to use the alpha channel to show the scalar values in B. In other words, if the value at a given coordinate in both A and B is large, then the pixel in the plot will be bright green and opaque. If it is large in A and not B, then it will be bright green but mostly transparent. And if it is large in B and not A, then it will be opaque but white.
However, the resulting image is not what I am expecting. My input data is called d
, and it is a combination of the RGB values that result from mapping the A array with a matplotlib colormap (i.e. mpl.cm.BuGn(A)
) and the B array.
Here I'm going to plot the full image (what I want to actually use), the RGB image (A, mapped with BuGn
), and the alpha-providing array (B, with a grayscale colormap).
f, (ax0, ax1, ax2) = plt.subplots(1, 3, figsize=(5, 2.5))
ax0.imshow(d)
ax1.imshow(d[..., :-1])
ax2.imshow(d[..., -1])
I am confused about where the splotchy gray junk in the full image is coming from, since there aren't any values in the colormap that are those colors. To show this effect more dramatically, I can change the bounds of the colormap so they are far away from the extremes of the data and re-plot:
I don't understand why pixels that are white with a large alpha value show up as gray. Opaque white should still be white.
Note that this behavior is different than if I plot the RGB component array and lower the transparancy with the alpha
kwarg, i.e. ax2.imshow(d[..., :-1], alpha=.3)
:
The revised answer by the venerable ballsdotballs seems plausible. From that mailing list post, it looks like handling of alpha values was not carefully thought out. Further, from the example in the original post, it seems to me that the alpha
arg in imshow
is composited differently than alpha numbers provided in RGBA data.
To work around whatever blending Agg is doing, one could avoid alpha and do the compositing manually.
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)
I'm sure there's a better way to do the reshaping, but that's not the issue here.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With