When using a decreasing Norm, colorbars show no ticks.
Code for reproduction
This example uses a PowerNorm-like norm which first applies the power, then does linear rescaling to (0, 1) (as opposed to matplotlib's PowerNorm which first linearly rescales to (0, 1) then applies the power) -- as argued in #10234 the behavior here is often more desirable, though that's not the point of this bug report.
PNorms with a negative gamma are decreasing (the builtin PowerNorm wouldn't work here because the first linear rescaling step would put the minimum to zero, which doesn't like being raised to a negative power...).
If you make that True, it does an OK job of labeling the ticks, but they are equally scaled between 1 and 100 and you probably want a logarithmic scaling, or an arbitrary scale? As pointed out before, we don't have arbitrary scales for axis, so thats a bit messy. I think you have to do something by hand here.
Happy to discuss improving this API. Two different issues:
setting the scale of an axis to something more arbitrary than log and linear (and symlog, and a couple of others folks have added)
allowing other norms to be passed to automatic tick selection. How does the locator know what ticks to chose? Maybe the user needs to supply the locator?
Indeed, I forgot to mention another point which is that the colorbar should give equal space to each "unit-of-color" (rather than unit-of-unscaled value), similarly to what it currently does for LogNorm:
(compare with the PNorm(-2) colorbar which is basically useless (pretend that the values in the image are distributed such that we indeed get colors of each hue...)).
allowing other norms to be passed to automatic tick selection. How does the locator know what ticks to chose? Maybe the user needs to supply the locator?
As I already argued elsewhere, there is some machinery associating scales to tickers (Scale.set_default_locators_and_formatters); it would be nice if norms could reuse that (and then custom norms could need to implement their own set_default_locators_and_formatters, which is fine -- can't guess it).
OK, and maybe we also need a Norm.get_scale or scale.get_scale_from_norm and then the colorbar could use that as the scale rather than guessing the scale. They are such similar concepts that we should be able to make it easier to get from one to the other...
See #7294 and #7631 for some long and confused discussion about norms and scales... (I think(?) only one of them should exist: a Norm is nothing else than a Scale on the colorbar axis.)
OK, I always have to refresh myself on all this stuff...
Scales are wrappers around transforms
1. have set_default_locators_and_formatters method to set those
2. have limit_range_for_scale to clip the data, which I guess transforms don't have.
Normalize': 1. has an inverse 2. doesn't use Transforms`
3. Does some autoscaling
So, I think i agree that there isn't a huge difference between the two. Not sure what the path forward for homogenizing the two would be, but it seems possible.
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!
Activity
jklymak commented on Oct 29, 2018
Did this ever work or did we break something?
anntzer commented on Oct 29, 2018
Doesn't work at least as far back as 1.5.3.
jklymak commented on Oct 29, 2018
OK, maybe we've never supported non-fixed ticks for colorbars w/ arbitrary norms.
The approriate check is
matplotlib/lib/matplotlib/colorbar.py
Line 508 in ad779b4
If you make that True, it does an OK job of labeling the ticks, but they are equally scaled between 1 and 100 and you probably want a logarithmic scaling, or an arbitrary scale? As pointed out before, we don't have arbitrary scales for axis, so thats a bit messy. I think you have to do something by hand here.
Happy to discuss improving this API. Two different issues:
See #11859 for arbitrary scale discussion.
anntzer commented on Oct 29, 2018
Indeed, I forgot to mention another point which is that the colorbar should give equal space to each "unit-of-color" (rather than unit-of-unscaled value), similarly to what it currently does for LogNorm:

(compare with the PNorm(-2) colorbar which is basically useless (pretend that the values in the image are distributed such that we indeed get colors of each hue...)).
As I already argued elsewhere, there is some machinery associating scales to tickers (Scale.set_default_locators_and_formatters); it would be nice if norms could reuse that (and then custom norms could need to implement their own set_default_locators_and_formatters, which is fine -- can't guess it).
jklymak commented on Oct 29, 2018
OK, and maybe we also need a Norm.get_scale or scale.get_scale_from_norm and then the colorbar could use that as the scale rather than guessing the scale. They are such similar concepts that we should be able to make it easier to get from one to the other...
anntzer commented on Oct 29, 2018
See #7294 and #7631 for some long and confused discussion about norms and scales... (I think(?) only one of them should exist: a Norm is nothing else than a Scale on the colorbar axis.)
jklymak commented on Oct 29, 2018
OK, I always have to refresh myself on all this stuff...
Scales are wrappers around transforms
1. have set_default_locators_and_formatters method to set those
2. have limit_range_for_scale to clip the data, which I guess transforms don't have.
Normalize': 1. has an inverse 2. doesn't use Transforms`
3. Does some autoscaling
So, I think i agree that there isn't a huge difference between the two. Not sure what the path forward for homogenizing the two would be, but it seems possible.
jklymak commented on Nov 15, 2018
#12808 is another example of this functionality being missing.
I'd propose that we get it working for axis objects first, and then worry about colorbars 😉
jklymak commented on Nov 15, 2018
#11859 (comment) for another comment on this.
github-actions commented on May 21, 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!
anntzer commented on May 21, 2023
This is effectively fixed by make_norm_from_scale, e.g.