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
Adding colorbar changes imshow plot color when vmin is close to vmax #5467
I can't tell whether this is an intended feature or a bug, so I'm going to run it by the group.
f = plt.figure()
mappable = plt.gca().imshow([[42]])
Here, we gave a single pixel, so the entire plot is the same color.
With default jet colormap, that single color is dark blue (the bottom of the jet cmap). So far so good.
f.colorbar(mappable)
Here, observe that since vmin==vmax (effectively), the colorbar defaulted to the midpoint of the colormap, now green. Luckily, the Axes from imshow, containing the data, changed too!
On one hand, I like that the colorbar shows context around the singular value. (I think due to this line.) On the other hand, over in Geopandas we plot patches one-by-one with face_color values from a normalized colormap, but adding this renormalization means the colorbar no longer matches the cmap I passed it.
Thoughts? If you tell me this is intended I'm willing to find a workaround to my use case. (Frankly I'm not 100% sure what I would expect matplotlib to do here instead.) Just wanted to get a second opinion.
@tacaswell Thanks for the PatchCollections tip, they do give better performance! But sometimes we'll have a GeoSeries with multiple geometry types, requiring multiple Collections. I can't find a way to have two different Collections share the same colormap using collection.set_array(), so I still end up explicitly setting the colors on each Collection to the result of mappable.to_rgba(values) -- which still has the bug mentioned above.
@tacaswell Each collection re-normalizes the colormap to its own range of values. So if collection1 has values in (0, 5) and collection2 has values in (20, 25), each with set_map('RdBu'), I wanted collection1 (low values) to be in the reds and collection2 (high values) to be in the blues.
I was able to do this by setting set_clim to the absolute min and max on both collections. Problem solved! (The behavior mentioned in the issue title is still a problem though.)
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!
I still notice the behavior from the issue title ("adding colorbar changes imshow plot color") but I'm not convinced if this behavior is buggy. Let's let this go. Closing.
Re-reading this, I think I agree. We are in a bit of a bind. If you want a colorbar, the norm must not be singular so our options are to expand the norm or to raise and I think this is a case where expanding is reasonable.
Currently if you set the norm to be singular after the colorbar is added it will re-expand itself.
Activity
mdboom commentedon Nov 12, 2015
Cc: @efiring
tacaswell commentedon Nov 12, 2015
We probably should push the range expansion logic up (down?) into
ColorMappable.@IamJeffG You might be better performance if you use
PatchCollectionand we will do the color mapping for you.IamJeffG commentedon Jan 10, 2016
@tacaswell Thanks for the
PatchCollectionstip, they do give better performance! But sometimes we'll have a GeoSeries with multiple geometry types, requiring multiple Collections. I can't find a way to have two different Collections share the same colormap usingcollection.set_array(), so I still end up explicitly setting the colors on each Collection to the result ofmappable.to_rgba(values)-- which still has the bug mentioned above.tacaswell commentedon Feb 1, 2016
@IamJeffG
mappable.set_map(cm)does not work?IamJeffG commentedon Feb 16, 2016
@tacaswell Each collection re-normalizes the colormap to its own range of values. So if
collection1has values in (0, 5) andcollection2has values in (20, 25), each withset_map('RdBu'), I wantedcollection1(low values) to be in the reds andcollection2(high values) to be in the blues.I was able to do this by setting
set_climto the absolute min and max on both collections. Problem solved! (The behavior mentioned in the issue title is still a problem though.)github-actions commentedon Jun 5, 2023
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!
IamJeffG commentedon Jun 8, 2023
I still notice the behavior from the issue title ("adding colorbar changes imshow plot color") but I'm not convinced if this behavior is buggy. Let's let this go. Closing.
tacaswell commentedon Jun 8, 2023
Thanks @IamJeffG .
Re-reading this, I think I agree. We are in a bit of a bind. If you want a colorbar, the norm must not be singular so our options are to expand the norm or to raise and I think this is a case where expanding is reasonable.
Currently if you set the norm to be singular after the colorbar is added it will re-expand itself.