Skip to content

Add alpha-array support to _rgb_to_rgba #26520

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 11 additions & 6 deletions lib/matplotlib/image.py
Original file line number Diff line number Diff line change
Expand Up @@ -215,17 +215,16 @@
return out


def _rgb_to_rgba(A):
def _rgb_to_rgba(A, alpha=None):
"""
Convert an RGB image to RGBA, as required by the image resample C++
extension.
"""
rgba = np.zeros((A.shape[0], A.shape[1], 4), dtype=A.dtype)
if alpha is None or np.ndim(alpha) == 0:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what input is np.ndim(alpha) == 0 addressing?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Scalar alpha input should remaing unaffected by new code. This ensures just that

alpha = 255 if A.dtype == np.uint8 else 1.0
rgba[:, :, :3] = A
if rgba.dtype == np.uint8:
rgba[:, :, 3] = 255
else:
rgba[:, :, 3] = 1.0
rgba[:, :, 3] = alpha
return rgba


Expand Down Expand Up @@ -582,7 +581,13 @@
else:
if A.ndim == 2: # interpolation_stage = 'rgba'
self.norm.autoscale_None(A)
A = self.to_rgba(A)
A = self.to_rgba(A, alpha=self.get_alpha())
elif A.shape[2] == 3:
A = _rgb_to_rgba(A, alpha=self.get_alpha())
elif A.shape[2] == 4:
array_alpha = self.get_alpha()
if array_alpha is not None and np.ndim(array_alpha) != 0:
A[:, :, 3] *= array_alpha # blend alphas of image and param

Check warning on line 590 in lib/matplotlib/image.py

View check run for this annotation

Codecov / codecov/patch

lib/matplotlib/image.py#L590

Added line #L590 was not covered by tests
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This modifies A in place where as in the other branches we get a copy of A back. Because it modifies in in place and we cache A higher up in the call stack it will apply the alpha everytime it draws.

alpha = self._get_scalar_alpha()
if A.shape[2] == 3:
# No need to resample alpha or make a full array; NumPy will expand
Expand Down
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
215 changes: 215 additions & 0 deletions lib/matplotlib/tests/baseline_images/test_image/image_alpha_array.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
16 changes: 16 additions & 0 deletions lib/matplotlib/tests/test_image.py
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,22 @@ def test_image_alpha():
ax3.imshow(Z, alpha=0.5, interpolation='nearest')


@image_comparison(['image_alpha_array'], remove_text=True)
def test_image_alpha_array():
_, ax = plt.subplots()

# create a 2x2 grid. If alpha is applying correctly,
# the top half should not match the 0.5 valued pixel
# in the bottom half.
arr = np.array([[.5, .5], [.75, .5]])
cmap = plt.get_cmap('gray')
norm = colors.Normalize()
arr_rgb = cmap(norm(arr))[:, :, :3]
alpha = np.ones_like(arr)
alpha[:1] = 0.2
ax.imshow(arr, alpha=alpha, cmap='gray', interpolation='none')
Comment on lines +258 to +271
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can be better written as a check_figures_equal test. Compare a (n, m, 3) array plus additional alpha to the same plot with a (n, m, 4) array.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is also concerning that the png and svg images are different....



@mpl.style.context('mpl20')
@check_figures_equal(extensions=['png'])
def test_imshow_alpha(fig_test, fig_ref):
Expand Down
Loading