-
-
Notifications
You must be signed in to change notification settings - Fork 7.9k
[Bug]: Image color limits not correctly updated with set_clim() IFF color bar present AND new norm.vmin > old norm.vmax #29522
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
Workaround for this bug (based on example code):
|
I can confirm this on latest Matplotlib. Thanks for the clear minimal report. @greglucas I wonder if this has to do with your colorbar interactivity? |
Yes, I think it does have to do with the signals on the norm callbacks. We trigger the signals when setting vmin originally, which then becomes greater than the original vmax (vmin > vmax temporarily). We emit a norm-has-changed signal and then the colorbar goes and processes values and then we have a non-singular expansion which swaps the vmin/vmax if they are inverted. matplotlib/lib/matplotlib/colorbar.py Lines 1104 to 1105 in 9e3ada3
@erikdendekker that is why you are seeing that behavior of the order of setting vmin/vmax mattering in your workaround. I'm not sure what exactly the proper fix is here. We are triggering callbacks, which trigger colorbar processing before we have finished updating all of our norm limits which the colorbar doesn't like. We could fix the |
@erikdendekker in your workaround you have same statements in your if and else blocks,
|
This happening within a single I think it comes down to a question of when should we enforce that the colormappable is in a consistent drawable state. The options I see are:
I not sure any of these are wrong (and we have behavior in the library of all three types). Currently setting This seems related to discussion we had about colorbars and auto-scaling for constant value data (however I am failing to find the issue), we should be consistent with our decision there. |
That‘s #26307. The main point of discussion there is to which color value we should map, not so much when. |
I think there's also the question of whether we could support norms with vmin > vmax (and e.g. treat them as reversing the colormap). Somewhat related to #12665 I guess, although that's a fairly old issue. (edited typo, was initially incorrectly |
You mean vmin > vmax? I'm a bit hesitant. Is there a use case where that's natural? I suspect that this may rather be indicative of a calculation or input error, and we should raise instead. If people want to explicitly reverse the colormap they should use the "..._r" version of the colormap. |
For sure there are instances where the colorbar makes more sense if it is inverted, but keeping the values on the colorbar positive. Eg depth goes from 5000 to zero but you want the darkest blue to be 5000. Currently you'd need to reverse the colormap and reverse the colorbar, or use negative depths and change the ticks. I don't think it's a big deal. Personally I just use negative depths in the colorbar, but if someone were more persnickety, you could imagine them being saved a song and dance if we allowed inverted norms. |
For the simple code that reproduces this bug you are right of course,.. In my real-world application, image data is interactively updated from an external source and shown to the user. I just encountered unexpected behaviour in some specific cases, was able to pinpoint it to this issue, and condensed it to the simplified example. |
Interestingly, the colorbar modifies the norm:
Prints
This is definitively undesired. Norms itself currently raise if
This may be too clever. IMHO it makes reasoning on the mapping harder. Instead I suggest to invert the colorbar Axes.`
We could even grow a kwarg on |
@timhoffm, I agree. In my view, the colorbar should only "query" the norm and use that (interactive axes updating the norm for colorbars is separate and explicit), otherwise we have a divergence between images with/without colorbars. If we can push all of this logic over into the mappable drawing (and perhaps call that similar to matplotlib/lib/matplotlib/colorbar.py Lines 1097 to 1108 in 9e3ada3
|
I've not looked into the details but I'm hesitant to move the non-singular expansion into the mappable. This ties again into #26307. It's a fundamental question how to handle singularity:
|
re: supporting inverted norms (I commented on the other thread re: singular norms): assuming this does not introduce too many complications elsewhere (e.g. re: inverted colorbars), I think making |
…29590) * Blocked set_clim() callbacks to prevent inconsistent state (#29522) * added test for set_clim() callback count * Relocated test_set_clim_emits_single_callback to test_colors.py * test case corrections --------- Co-authored-by: prafulgulani555 <59774145+prafulgulani555@users.noreply.github.com>
… inconsistent state (matplotlib#29522)
Bug summary
I experienced some specific odd cases where I noticed that the colors of an image were not correctly set after updating the image data and setting new color limits with set_clim(). After debugging I was able to reproduce with a minimal example,..
Code for reproduction
Actual outcome
Expected outcome
Additional information
Only happens if color bar is present; Removing the line that creates it from code lets you see the correct image (minus color bar).
Data dependent; Only occurs if the lowest value of the new image data is higher than the highest value of the old image data (Hence +10 in the code example).
Operating system
Windows 10
Matplotlib Version
Matplotlib Backend
QtAgg
Python version
3.11.9
Jupyter version
Installation
pip
The text was updated successfully, but these errors were encountered: