You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
imshow with LogNorm crashes with certain inputs #18415
Due to changes introduced in 3dea5c7, trying to display some images with LogNorm will crash because vmin gets auto-adjusted to 0 (which is invalid for LogNorm).
File "C:\Python38\lib\site-packages\matplotlib\image.py", line 922, in make_image
return self._make_image(self._A, bbox, transformed_bbox, clip,
File "C:\Python38\lib\site-packages\matplotlib\image.py", line 541, in _make_image
output = self.norm(resampled_masked)
File "C:\Python38\lib\site-packages\matplotlib\colors.py", line 1193, in __call__
self._check_vmin_vmax()
File "C:\Python38\lib\site-packages\matplotlib\colors.py", line 1182, in _check_vmin_vmax
raise ValueError("minvalue must be positive")
ValueError: minvalue must be positive
Expected outcome
Showed a plot in MPL 3.1 (and I believe every version until 3.3). The crash is coming from _make_image transforming vmin to be zero per changes added in 3dea5c7. I guess perhaps the solution is "then don't try to plot that, use a vmin closer to your vmax" but kind of inconvenient for code that previously worked fine.
in #16910 the issue is the in the round-tripping of rescaling the data (but not the limits) we were bouncing values exactly equal to the limit across the edge and erroneously marking them as over/under. The theory of #17636 is that by transforming both the limits and the data together we would preserve the relative ordering of vmin / vmax and the data under all cases (which I still think is correct). The issue is that now we have the vmin is bouncing across the valid values for vmin for the log norm.
We don't do any validation when setting vmin / vmax (they are normal attributes) so we don't have a good way to hook this on the norm side (and up-converting to properties is not good enough because in other cases we if the user sets the limits to be out of range we would want to fail instead of silently clipping.
We could hard code a special case for LogNorm and cilp the vmin to 0+eps before sending it in. It is pragmatic and would not be the first time that we have isinstance checks for LogNorm around.
We could add (optional) public or private API to the norm to class to allow it to express what its valid range is (either a class-level limits or a class level "clip to valid" function).
I don't think there is any path to trying to "guess" what the right thing to do here is as if there was also data at 100 it would have the same problem and be pushed across the edge to "invalid".
I'm leaning towards doing the "hard-coded-fix" for 3.3.2 and a more extendable fix for 3.4.
Activity
tacaswell commentedon Sep 9, 2020
Yikes, sorry about that. This is not the first issue we have had with the limitations of float precision / range...
tacaswell commentedon Sep 11, 2020
in #16910 the issue is the in the round-tripping of rescaling the data (but not the limits) we were bouncing values exactly equal to the limit across the edge and erroneously marking them as over/under. The theory of #17636 is that by transforming both the limits and the data together we would preserve the relative ordering of vmin / vmax and the data under all cases (which I still think is correct). The issue is that now we have the vmin is bouncing across the valid values for vmin for the log norm.
We don't do any validation when setting vmin / vmax (they are normal attributes) so we don't have a good way to hook this on the norm side (and up-converting to properties is not good enough because in other cases we if the user sets the limits to be out of range we would want to fail instead of silently clipping.
We could hard code a special case for LogNorm and cilp the vmin to 0+eps before sending it in. It is pragmatic and would not be the first time that we have isinstance checks for
LogNormaround.We could add (optional) public or private API to the norm to class to allow it to express what its valid range is (either a class-level limits or a class level "clip to valid" function).
I don't think there is any path to trying to "guess" what the right thing to do here is as if there was also data at 100 it would have the same problem and be pushed across the edge to "invalid".
I'm leaning towards doing the "hard-coded-fix" for 3.3.2 and a more extendable fix for 3.4.
FIX: special-case LogNorm when resealing