Skip to content

[Bug]: pcolormesh writing to input mask #26093

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

Closed
rcomer opened this issue Jun 8, 2023 · 2 comments · Fixed by #26223
Closed

[Bug]: pcolormesh writing to input mask #26093

rcomer opened this issue Jun 8, 2023 · 2 comments · Fixed by #26223

Comments

@rcomer
Copy link
Member

rcomer commented Jun 8, 2023

Bug summary

When pcolormesh receives a masked array, it seems to be writing back to the mask. Since numpy 1.24 this now causes pcolormesh to fail if the mask is read-only.

Code for reproduction

import matplotlib.pyplot as plt
import numpy as np

data = np.arange(6).reshape(2, 3)
mask = np.broadcast_to([False, True, False], data.shape)  # read-only array

masked_data = np.ma.array(data, mask=mask)

plt.pcolormesh(masked_data)

Actual outcome

Traceback (most recent call last):
  File "pcolormesh_read_only_mask.py", line 9, in <module>
    plt.pcolormesh(masked_data)
  File "[conda-env-path]/lib/python3.11/site-packages/matplotlib/pyplot.py", line 2773, in pcolormesh
    __ret = gca().pcolormesh(
            ^^^^^^^^^^^^^^^^^
  File "[conda-env-path]/lib/python3.11/site-packages/matplotlib/__init__.py", line 1442, in inner
    return func(ax, *map(sanitize_sequence, args), **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "[conda-env-path]/lib/python3.11/site-packages/matplotlib/axes/_axes.py", line 6220, in pcolormesh
    X, Y, C, shading = self._pcolorargs('pcolormesh', *args,
                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "[conda-env-path]/lib/python3.11/site-packages/matplotlib/axes/_axes.py", line 5704, in _pcolorargs
    C = cbook.safe_masked_invalid(C)
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "[conda-env-path]/lib/python3.11/site-packages/matplotlib/cbook/__init__.py", line 715, in safe_masked_invalid
    xm = np.ma.masked_invalid(x, copy=False)
         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "[conda-env-path]/lib/python3.11/site-packages/numpy/ma/core.py", line 2360, in masked_invalid
    res = masked_where(~(np.isfinite(a)), a, copy=copy)
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "[conda-env-path]/lib/python3.11/site-packages/numpy/ma/core.py", line 1942, in masked_where
    result.mask = _shrink_mask(cond)
    ^^^^^^^^^^^
  File "[conda-env-path]/lib/python3.11/site-packages/numpy/ma/core.py", line 3516, in mask
    self.__setmask__(value)
  File "[conda-env-path]/lib/python3.11/site-packages/numpy/ma/core.py", line 3462, in __setmask__
    current_mask.flat = mask
    ^^^^^^^^^^^^^^^^^
ValueError: array is read-only

Expected outcome

No error

Additional information

The code above runs fine with numpy v1.23, although the output from broadcast_to was already read-only at that version. From numpy release notes, this looks like the likely reason for the change:
https://numpy.org/doc/stable/release/1.24.0-notes.html#masked-invalid-now-modifies-the-mask-in-place

Aside from the new error, if a user passes a masked array that has nans or infs at the unmasked points, we are modifying their input array with the call to masked_invalid.

I guess we just need to take a copy somewhere?

Operating system

RHEL7

Matplotlib Version

3.7.1

Matplotlib Backend

QtAgg

Python version

3.11.3

Jupyter version

N/A

Installation

conda

@tacaswell tacaswell added this to the v3.7.2 milestone Jun 8, 2023
@Rylie-W
Copy link

Rylie-W commented Jun 28, 2023

Hi @rcomer, could I try to work on this issue?

@melissawm
Copy link
Member

melissawm commented Jun 28, 2023

@Rylie-W we don't assign issues, so feel free to go for it 😄 Make sure to ping if you have questions.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants