Skip to content

Fix imshow to support array alpha values and add corresponding test #30407

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 1 commit into
base: main
Choose a base branch
from

Conversation

YogeshCruz
Copy link

@YogeshCruz YogeshCruz commented Aug 8, 2025

PR summary

This PR updates the imshow() functionality to support array-like values for the alpha parameter. This allows for per-pixel alpha transparency, enabling more advanced visualization use-cases.

Why is this change necessary?

Currently, imshow() only supports scalar values for alpha, limiting how transparency is applied across an image. Allowing alpha to be an array enables gradient effects and blending operations.

What problem does it solve?

Fixes behavior where alpha as an array would previously raise an error or be ignored. This makes imshow more consistent with other plotting APIs and improves flexibility.

Implementation Notes

  • _set_alpha_for_array method now handles array-like alpha correctly.
  • A new test has been added to test_axes/test_imshow_alpha_array.py.

PR checklist

  • closes #0000 (if there's a related issue, replace 0000 with the number — otherwise leave this unchecked)
  • new and changed code is tested
  • Plotting related features are demonstrated in an example/test
  • New Features and API Changes are noted with a release note
  • Documentation complies with guidelines

@melissawm
Copy link
Member

Hi @YogeshCruz - before this is reviewed it may be useful to fix the currently failing tests. Thanks!

@timhoffm
Copy link
Member

timhoffm commented Aug 8, 2025

What exactly is not working? This works as of 3.10.5

import numpy as np
import matplotlib.pyplot as plt

data = np.array([0, 1]* 50).reshape(10, 10)
alpha = np.linspace(0, 1, 100).reshape(10, 10)

plt.imshow(data, alpha=alpha)
image

@timhoffm timhoffm added the status: needs clarification Issues that need more information to resolve. label Aug 8, 2025
@YogeshCruz
Copy link
Author

YogeshCruz commented Aug 8, 2025

What exactly is not working? This works as of 3.10.5

import numpy as np
import matplotlib.pyplot as plt

data = np.array([0, 1]* 50).reshape(10, 10)
alpha = np.linspace(0, 1, 100).reshape(10, 10)

plt.imshow(data, alpha=alpha)
image

Thanks @timhoffm for checking it!
The issue I was addressing is about ensuring the shape and dtype of the alpha parameter matches data and gets properly validated especially in edge cases or malformed inputs.

It seems this case works as expected on 3.10.5. I will re-run my tests locally, clean up the failing ones, and update the PR with proper test coverage and code comments to clarify the fix.

Also, I’m facing some local setup issues now previously it worked, but now tests aren’t running due to build errors. I’m working to resolve that and will push a cleaner version soon.

@rcomer
Copy link
Member

rcomer commented Aug 8, 2025

@YogeshCruz please could you post some example code that does not work as expected in v3.10.5? Often when someone thinks they have found a bug, it turns out not to be. It would be a shame to go to the effort of updating your branch if this is one of those cases. If you provide some example code then we can discuss whether there really is a problem.

@YogeshCruz
Copy link
Author

YogeshCruz commented Aug 8, 2025

@YogeshCruz please could you post some example code that does not work as expected in v3.10.5? Often when someone thinks they have found a bug, it turns out not to be. It would be a shame to go to the effort of updating your branch if this is one of those cases. If you provide some example code then we can discuss whether there really is a problem.

You're absolutely right I understand that sometimes what seems like a bug may be expected behavior. Here's a minimal reproducible example that demonstrates the issue I'm seeing in v3.10.5:

import numpy as np
import matplotlib.pyplot as plt

data = np.random.rand(10, 10)
alpha = np.linspace(0, 1, 10).reshape((10, 1))

plt.imshow(data, alpha=alpha)
plt.colorbar()
plt.show()

In this version, passing a 2D alpha array with the same shape as data doesn't apply the per-pixel alpha as expected instead, it raises an error or behaves inconsistently.

If this is intended behavior, I'm happy to close the issue or update the approach accordingly. I just wanted to double-check before proceeding further.

Thanks again for your time and guidance!

@timhoffm
Copy link
Member

timhoffm commented Aug 8, 2025

Ok, so the issue is that, if the alpha-array size does not match the image size, then funny things can happen.

The fix is to check for the appropriate shape here:

if np.ndim(alpha) not in (0, 2):
raise TypeError('alpha must be a float, two-dimensional '
'array, or None')
self._imcache = None

@YogeshCruz
Copy link
Author

Ok, so the issue is that, if the alpha-array size does not match the image size, then funny things can happen.

The fix is to check for the appropriate shape here:

matplotlib/lib/matplotlib/image.py

Lines 312 to 315 in 40a47e5

Thank you for the clarification!

You're right the core issue arises when the shape of the alpha array doesn't match the image dimensions, leading to unexpected behavior. Adding a shape check in image.py (specifically around lines 312–315) makes sense to catch these mismatches early and provide a clearer error or fallback.

I'll update the branch accordingly to include this validation. Appreciate your guidance on this will follow up once the patch is ready.

@jklymak
Copy link
Member

jklymak commented Aug 8, 2025

I guess it's open to interpretation if that is what people want. The alpha above is one column, so what happens is the first column of the image is shown, and the other 9 are invisible, presumably corresponding to alpha=0 for those cells. I guess I'd prefer an error here, but maybe someone wanted it this way for a reason?

@rcomer
Copy link
Member

rcomer commented Aug 8, 2025

The imshow docs state

If alpha is an array, the alpha blending values are applied pixel by pixel, and alpha must have the same shape as X.

I think I would expect it to either error or broadcast, though the user can of course do their own broadcasting.

@YogeshCruz
Copy link
Author

I guess it's open to interpretation if that is what people want. The alpha above is one column, so what happens is the first column of the image is shown, and the other 9 are invisible, presumably corresponding to alpha=0 for those cells. I guess I'd prefer an error here, but maybe someone wanted it this way for a reason?

I think raising an error for mismatched alpha array shapes would be safer. The current behavior might work for intentional broadcasting, but it’s more likely to hide mistakes. An explicit check would make the behavior clearer and prevent unintended results.

@YogeshCruz
Copy link
Author

I think I would expect it to either error or broadcast, though the user can of course do their own broadcasting.

Agreed, either explicit broadcasting or an error would make the behavior predictable. Silent partial application of alpha feels too implicit and could easily mask mistakes.

@dstansby dstansby added status: needs revision and removed status: needs clarification Issues that need more information to resolve. labels Aug 12, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: Needs review
Development

Successfully merging this pull request may close these issues.

6 participants