Skip to content

Commit b83305e

Browse files
authored
Fix array alpha to multiply (not replace) existing RGBA alpha (#30795)
2 parents 86f65d7 + cf9037e commit b83305e

File tree

3 files changed

+15
-9
lines changed

3 files changed

+15
-9
lines changed
Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
*alpha* parameter handling on images
22
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
33

4-
When passing and array to ``imshow(..., alpha=...)``, the parameter was silently ignored
5-
if the image data was an RGB or RBGA image or if :rc:`image.interpolation_stage`
6-
resolved to "rbga".
4+
Prior to Matplotlib 3.10.1, when passing an array to ``imshow(..., alpha=...)``, the
5+
parameter was silently ignored if the image data was an RGB or RGBA image or if
6+
:rc:`image.interpolation_stage` resolved to "rbga".
77

8-
This is now fixed, and the alpha array overwrites any previous transparency information.
8+
Matplotlib 3.10.1 changed this to apply the alpha array as the alpha channel,
9+
overwriting any existing transparency information in the image data. Matplotlib v3.11.0
10+
further fixes the handling for RGBA images: the existing alpha channel is now multiplied
11+
by the alpha array, consistent with how scalar alpha values are handled.

lib/matplotlib/image.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -515,8 +515,10 @@ def _make_image(self, A, in_bbox, out_bbox, clip_bbox, magnification=1.0,
515515
if A.shape[2] == 3: # image has no alpha channel
516516
A = np.dstack([A, np.ones(A.shape[:2])])
517517
elif np.ndim(alpha) > 0: # Array alpha
518-
# user-specified array alpha overrides the existing alpha channel
519-
A = np.dstack([A[..., :3], alpha])
518+
if A.shape[2] == 3: # RGB: use array alpha directly
519+
A = np.dstack([A, alpha])
520+
else: # RGBA: multiply existing alpha by array alpha
521+
A = np.dstack([A[..., :3], A[..., 3] * alpha])
520522
else: # Scalar alpha
521523
if A.shape[2] == 3: # broadcast scalar alpha
522524
A = np.dstack([A, np.full(A.shape[:2], alpha, np.float32)])

lib/matplotlib/tests/test_image.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1864,7 +1864,7 @@ def test_interpolation_stage_rgba_respects_alpha_param(fig_test, fig_ref, intp_s
18641864
axs_ref[0][2].imshow(im_rgba, interpolation_stage=intp_stage)
18651865

18661866
# When the image already has an alpha channel, multiply it by the
1867-
# scalar alpha param, or replace it by the array alpha param
1867+
# alpha param (both scalar and array alpha multiply the existing alpha)
18681868
axs_tst[1][0].imshow(im_rgba)
18691869
axs_ref[1][0].imshow(im_rgb, alpha=array_alpha)
18701870
axs_tst[1][1].imshow(im_rgba, interpolation_stage=intp_stage, alpha=scalar_alpha)
@@ -1876,8 +1876,9 @@ def test_interpolation_stage_rgba_respects_alpha_param(fig_test, fig_ref, intp_s
18761876
new_array_alpha = np.random.rand(ny, nx)
18771877
axs_tst[1][2].imshow(im_rgba, interpolation_stage=intp_stage, alpha=new_array_alpha)
18781878
axs_ref[1][2].imshow(
1879-
np.concatenate( # combine rgb channels with new array alpha
1880-
(im_rgb, new_array_alpha.reshape((ny, nx, 1))), axis=-1
1879+
np.concatenate( # combine rgb channels with multiplied array alpha
1880+
(im_rgb, array_alpha.reshape((ny, nx, 1))
1881+
* new_array_alpha.reshape((ny, nx, 1))), axis=-1
18811882
), interpolation_stage=intp_stage
18821883
)
18831884

0 commit comments

Comments
 (0)