Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 44770ae

Browse filesBrowse files
authored
Merge pull request #28437 from chaoyihu/imshow-alpha-not-respected
Respect array alpha with interpolation_stage='rgba' in _Imagebase::_make_image
2 parents 177f28c + 8a032c1 commit 44770ae
Copy full SHA for 44770ae

File tree

3 files changed

+75
-11
lines changed
Filter options

3 files changed

+75
-11
lines changed
+8Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
*alpha* parameter handling on images
2+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3+
4+
When passing and array to ``imshow(..., alpha=...)``, the parameter was silently ignored
5+
if the image data was a RGB or RBGA image or if :rc:`interpolation_state`
6+
resolved to "rbga".
7+
8+
This is now fixed, and the alpha array overwrites any previous transparency information.

‎lib/matplotlib/image.py

Copy file name to clipboardExpand all lines: lib/matplotlib/image.py
+21-11Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -501,17 +501,27 @@ def _make_image(self, A, in_bbox, out_bbox, clip_bbox, magnification=1.0,
501501
if A.ndim == 2: # interpolation_stage = 'rgba'
502502
self.norm.autoscale_None(A)
503503
A = self.to_rgba(A)
504-
alpha = self._get_scalar_alpha()
505-
if A.shape[2] == 3:
506-
# No need to resample alpha or make a full array; NumPy will expand
507-
# this out and cast to uint8 if necessary when it's assigned to the
508-
# alpha channel below.
509-
output_alpha = (255 * alpha) if A.dtype == np.uint8 else alpha
510-
else:
511-
output_alpha = _resample( # resample alpha channel
512-
self, A[..., 3], out_shape, t, alpha=alpha)
513-
output = _resample( # resample rgb channels
514-
self, _rgb_to_rgba(A[..., :3]), out_shape, t, alpha=alpha)
504+
alpha = self.get_alpha()
505+
if alpha is None: # alpha parameter not specified
506+
if A.shape[2] == 3: # image has no alpha channel
507+
output_alpha = 255 if A.dtype == np.uint8 else 1.0
508+
else:
509+
output_alpha = _resample( # resample alpha channel
510+
self, A[..., 3], out_shape, t)
511+
output = _resample( # resample rgb channels
512+
self, _rgb_to_rgba(A[..., :3]), out_shape, t)
513+
elif np.ndim(alpha) > 0: # Array alpha
514+
# user-specified array alpha overrides the existing alpha channel
515+
output_alpha = _resample(self, alpha, out_shape, t)
516+
output = _resample(
517+
self, _rgb_to_rgba(A[..., :3]), out_shape, t)
518+
else: # Scalar alpha
519+
if A.shape[2] == 3: # broadcast scalar alpha
520+
output_alpha = (255 * alpha) if A.dtype == np.uint8 else alpha
521+
else: # or apply scalar alpha to existing alpha channel
522+
output_alpha = _resample(self, A[..., 3], out_shape, t) * alpha
523+
output = _resample(
524+
self, _rgb_to_rgba(A[..., :3]), out_shape, t)
515525
output[..., 3] = output_alpha # recombine rgb and alpha
516526

517527
# output is now either a 2D array of normed (int or float) data

‎lib/matplotlib/tests/test_image.py

Copy file name to clipboardExpand all lines: lib/matplotlib/tests/test_image.py
+46Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1711,3 +1711,49 @@ def test_resample_dtypes(dtype, ndim):
17111711
axes_image = ax.imshow(data)
17121712
# Before fix the following raises ValueError for some dtypes.
17131713
axes_image.make_image(None)[0]
1714+
1715+
1716+
@pytest.mark.parametrize('intp_stage', ('data', 'rgba'))
1717+
@check_figures_equal()
1718+
def test_interpolation_stage_rgba_respects_alpha_param(fig_test, fig_ref, intp_stage):
1719+
axs_tst = fig_test.subplots(2, 3)
1720+
axs_ref = fig_ref.subplots(2, 3)
1721+
ny, nx = 3, 3
1722+
scalar_alpha = 0.5
1723+
array_alpha = np.random.rand(ny, nx)
1724+
1725+
# When the image does not have an alpha channel, alpha should be specified
1726+
# by the user or default to 1.0
1727+
im_rgb = np.random.rand(ny, nx, 3)
1728+
im_concat_default_a = np.ones((ny, nx, 1)) # alpha defaults to 1.0
1729+
im_rgba = np.concatenate( # combine rgb channels with array alpha
1730+
(im_rgb, array_alpha.reshape((ny, nx, 1))), axis=-1
1731+
)
1732+
axs_tst[0][0].imshow(im_rgb)
1733+
axs_ref[0][0].imshow(np.concatenate((im_rgb, im_concat_default_a), axis=-1))
1734+
axs_tst[0][1].imshow(im_rgb, interpolation_stage=intp_stage, alpha=scalar_alpha)
1735+
axs_ref[0][1].imshow(
1736+
np.concatenate( # combine rgb channels with broadcasted scalar alpha
1737+
(im_rgb, scalar_alpha * im_concat_default_a), axis=-1
1738+
), interpolation_stage=intp_stage
1739+
)
1740+
axs_tst[0][2].imshow(im_rgb, interpolation_stage=intp_stage, alpha=array_alpha)
1741+
axs_ref[0][2].imshow(im_rgba, interpolation_stage=intp_stage)
1742+
1743+
# When the image already has an alpha channel, multiply it by the
1744+
# scalar alpha param, or replace it by the array alpha param
1745+
axs_tst[1][0].imshow(im_rgba)
1746+
axs_ref[1][0].imshow(im_rgb, alpha=array_alpha)
1747+
axs_tst[1][1].imshow(im_rgba, interpolation_stage=intp_stage, alpha=scalar_alpha)
1748+
axs_ref[1][1].imshow(
1749+
np.concatenate( # combine rgb channels with scaled array alpha
1750+
(im_rgb, scalar_alpha * array_alpha.reshape((ny, nx, 1))), axis=-1
1751+
), interpolation_stage=intp_stage
1752+
)
1753+
new_array_alpha = np.random.rand(ny, nx)
1754+
axs_tst[1][2].imshow(im_rgba, interpolation_stage=intp_stage, alpha=new_array_alpha)
1755+
axs_ref[1][2].imshow(
1756+
np.concatenate( # combine rgb channels with new array alpha
1757+
(im_rgb, new_array_alpha.reshape((ny, nx, 1))), axis=-1
1758+
), interpolation_stage=intp_stage
1759+
)

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.