10000 Un-mask any masked offsets by dstansby · Pull Request #14281 · matplotlib/matplotlib · GitHub
[go: up one dir, main page]

Skip to content

Un-mask any masked offsets #14281

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
wants to merge 1 commit into from
Closed

Conversation

dstansby
Copy link
Member

Fixes #14265. The problem was because offsets to a Collection were being given as a masked array, which was causing some values to be converted to nan somewhere down the transform call stack, even if none of the values in the masked array were masked. See below for the warning.

Although this does fix the problem, something doesn't feel quite right, but I'm struggling to pin down exactly what the root cause of the problem is. Maybe others will have a better idea though?

Traceback (most recent call last):
  File "test.py", line 9, in <module>
    plt.scatter(x, y)
  File "/Users/dstansby/github/matplotlib/lib/matplotlib/pyplot.py", line 2844, in scatter
    None else {}), **kwargs)
  File "/Users/dstansby/github/matplotlib/lib/matplotlib/__init__.py", line 1569, in inner
    return func(ax, *map(sanitize_sequence, args), **kwargs)
  File "/Users/dstansby/github/matplotlib/lib/matplotlib/axes/_axes.py", line 4528, in scatter
    self.add_collection(collection)
  File "/Users/dstansby/github/matplotlib/lib/matplotlib/axes/_base.py", line 1897, in add_collection
    self.update_datalim(collection.get_datalim(self.transData))
  File "/Users/dstansby/github/matplotlib/lib/matplotlib/collections.py", line 203, in get_datalim
    result = result.inverse_transformed(transData)
  File "/Users/dstansby/github/matplotlib/lib/matplotlib/transforms.py", line 520, in inverse_transformed
    return self.transformed(transform.inverted())
  File "/Users/dstansby/github/matplotlib/lib/matplotlib/transforms.py", line 513, in transformed
    return Bbox([ll, [lr[0], ul[1]]])
  File "/Users/dstansby/github/matplotlib/lib/matplotlib/transforms.py", line 737, in __init__
    points = np.asarray(points, float)
  File "/Users/dstansby/miniconda3/lib/python3.7/site-packages/numpy/core/numeric.py", line 538, in asarray
    return array(a, dtype, copy=False, order=order)
  File "/Users/dstansby/miniconda3/lib/python3.7/site-packages/numpy/ma/core.py", line 4299, in __float__
    warnings.warn("Warning: converting a masked element to nan.", stacklevel=2)
UserWarning: Warning: converting a masked element to nan.

@@ -149,6 +149,7 @@ def __init__(self,
self._uniform_offsets = None
if offsets is not None:
offsets = np.asanyarray(offsets, float)
offsets = np.ma.filled(offsets, 0)
Copy link
Member

Choose a reason for hiding this comment

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

This might happen to fix the scatter example, but I don't understand the logic of it--why should masked values in offsets be set to zero? I suspect the real problem with scatter and symlog is elsewhere. The points shouldn't be getting masked in the first place.

Copy link
Member Author

Choose a reason for hiding this comment

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

Hmm, do you remember why you masked them in e959692 then?

Copy link
Member

Choose a reason for hiding this comment

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

Yes. Originally, scatter handled masked values in any of its array inputs by forming a combined mask and then deleting the masked points from all of the arrays. The problem was that this led to a mismatch between the original input arrays and the plotted arrays, which caused trouble if the user subsequently tried to modify properties of the resulting collection. The solution was to let the collection handle the masked points instead of deleting them.
The problem that you are trying to fix here is only revealed, not caused, by this change--it is a problem related to an interaction between symlog and scatter, not a problem with the bad-value handling itself. It is related to the linear part of the symlog transformation. The mystery is why it shows up in scatter and not in plot. The points that are missing are those in the linear range; the default linthresh is 2.0, and the missing points are at 1 and 2.

Copy link
Member Author

Choose a reason for hiding this comment

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

Thanks for the explanation, going down the rabbit hole was driving me a bit nuts! I agree this isn't the right fix here, so will close the PR.

efiring added a commit to efiring/matplotlib that referenced this pull request May 21, 2019
By failing the copy the input array, SymmetricalLogTransform.transform_non_affine
was returning an array with points in the linear range masked.
Closes matplotlib#14265.   Replaces matplotlib#14281.
@dstansby dstansby closed this May 22, 2019
@dstansby dstansby deleted the coll-offset-ma branch May 22, 2019 21:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

symlog looses some points since 3.1.0 (example given)
2 participants
0