-
-
Notifications
You must be signed in to change notification settings - Fork 7.9k
plot.scatter: negative or null values lead to strange behavior on log scale #11898
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
Comments
Actually this looks like a bug in the way the autolimits are computed (panning the window down shows that the "missing" points are actually plotted, just below the default lower y bound). |
If you do |
I spent a while with this, but it has to do with |
I don't completely understand what's going on, so I hope it's enough to be on the right track. The issue seems to be related to the fact that matplotlib/lib/matplotlib/axes/_base.py Line 1847 in 93aadf5
But for some reason, the collection's For the OP's problematic script, the collection created by In[3]: collection.get_datalim(self.transData)
Out[3]: Bbox([[0.9939516129032259, -0.008116883116883133], [4.006048387096774, 100.00811688311691]]) And the
matplotlib/lib/matplotlib/axes/_base.py Lines 1932 to 1935 in 93aadf5
For the same script, but with In[2]: data_path
Out[2]:
Path(array([[ 1., 0.],
[ 2., 10.],
[ 3., 50.],
[ 4., 100.]]), None) And the correct I wasn't able to follow how the collection's BTW, this also happens with some other plot types that add collections: plt.hlines([-1, 1, 2, 3, 100], 0, 1)
plt.yscale('log')
x = [-1, 10, 20, 100]
plt.eventplot(x)
plt.xscale('log') |
I think it'd be better to fix what seems to be a bug in |
OK, This is all complicated, because of course the paths are in pixels, and the offsets are in data, so its not trivial to just pass in different transforms and expect it all to work. It seems a shame to not use the fast c-code, but its also not trivial to see how this can be fixed. |
@hershen I think your solution is the only one that will work. If you wanted to submit a pr that would be good. We may also just want to deprecate the autolim kwarg for add-collection since it doesn’t do the right thing. |
Sure, I'll be happy to submit a PR. Do you mind if I play around with it a bit more? Perhaps, the fact that the problem doesn't occur with I can also submit a PR fixing the problem for |
self.add_collection(collection, autolim=False)
xy = np.vstack((x, y)).T
self.dataLim.update_from_data_xy(xy, self.ignore_existing_data_limits,
updatex=True, updatey=True) "fixes" it for me. However that fails all the image tests for scatter. The fundamental problem is that this doesn't take into account large markers, which should theoretically get a (slightly) larger extent to encompass the marker. I'd argue that this extra extent to take into account the markers is not worth the extra complexity. But someone put some effort into almost making this work, so someone cared about it. Another approach is to try to figure out the transform logic and write a proper data-space version of |
Need to mask and ignore existing data lims. Still fails image tests with finite-sized markers... self.add_collection(collection, autolim=False)
xy = np.vstack((x[~x.mask], y[~y.mask])).T
self.ignore_existing_data_limits = False
self.dataLim.update_from_data_xy(xy, self.ignore_existing_data_limits,
updatex=True, updatey=True)
self.autoscale_view() |
This was mostly fixed by (I think) #13642, but the resulting autolimits remain non-optimal: |
This issue has been marked "inactive" because it has been 365 days since the last comment. If this issue is still present in recent Matplotlib releases, or the feature request is still wanted, please leave a comment and this label will be removed. If there are no updates in another 30 days, this issue will be automatically closed, but you are free to re-open or create a new issue if needed. We value issue reports, and this procedure is meant to help us resurface and prioritize issues that have not been addressed yet, not make them disappear. Thanks for your help! |
This seems to have been fixed. |
Bug report
Related issues have already been reported but I think a simpler case is worth mentioning:
Bug summary
With negative or null values, log scale fails (although it does not crashes) discarding (masking) more points than the ones corresponding to the invalid negative or null values. At least a WARNING would be welcome.
Code for reproduction
Normal behavior: only positive values in
y
:Actual outcome:

Bug: with value 0 in
y
(idem with negative values):Actual outcome: only the last point is displayed.
Expected outcome
I understand that default behavior is masking of non positive values. But it seems that more values are masked. I tried chaging parameter
nonposy
:plt.yscale('log', nonposy='clip')
but the behavior is the same.At least a WARNING should be displayed about presence of negative or null values not compatible with log scale.
Matplotlib version
print(matplotlib.get_backend())
): module://ipykernel.pylab.backend_inlinematplotlib installed from conda default.
The text was updated successfully, but these errors were encountered: