I think position of ticklabels on colorbars with LogNorm is sometimes weird, and I believe it wasn't like this in earlier versions, but I haven't checked that now. Namely, in the example below, I would expect the lowest ticklabel be at 5x10-1, not 6x10-1 as it is now.
At least in matplotlib 2.0.2, the resulting image is the same as shown above.
In matplotlib 1.5.3 the resulting image is
In current master, the result is
where something strange is happending with the formatting, probably the same issue as #12488.
That being said, I think having the lower end ticked and labeled if it falls on a "useful" number may be more appealing; but expectations might be different here for different cases, such that finding a good default is not obvious.
You can decide to have all minor ticks labelled (which would result in crowded axes here) or none (which would not show any label except the10^1), or, you can have "nice" labels (the default). This is hardcoded to be [1,2,3,4,6,10]*10^exp
On a by-case basis you may of course use your own locations
import matplotlib.pyplot as plt
import numpy as np
from matplotlib.colors import LogNorm
from matplotlib.ticker import LogFormatterSciNotation
plt.imshow(np.random.random(15**2).reshape((15, 15))+0.5,
norm=LogNorm(vmax=2, vmin=0.5), cmap='coolwarm')
class MF(LogFormatterSciNotation):
def set_locs(self, locs=None):
self._sublabels = set([1,2,5,10])
cb = plt.colorbar(format=MF())
plt.show()
Having an interface for those of the style LogFormatter(..., sublabels=None) would be an option to add. In case sublabels are provided, minor_thresholds would be ignored, and self._sublabels = sublabels being set.
Just to clarify. On 3.0.0 the auto ticks should be the same as for any other log axis. That is a change as before colorbars drew their own ticks and labels.
No, for the code shown here, the "formatting (superscript vs inline math) issue" does not appear in version 2.2.2 (which @Phlya is using). Neither in matplotlib 3.0.0. (sorry, wrong env used)
It only appears in the master branch and (edit ->) in matplotlib 3.0.0.
Having an interface for those of the style LogFormatter(..., sublabels=None) would be an option to add. In case sublabels are provided, minor_thresholds would be ignored, and self._sublabels = sublabels being set.
This seems a reasonable feature request to me. I actually am not sure I like the defaults....
I keep stumbling upon this issue - I often use LogNorm with values around 1 in the range as used above.
I was just now trying to reproduce the custom subclass from #12503 (comment) to fix this, but it doesn't seem to work:
classMF(LogFormatter):
defset_locs(self, locs=None):
self._sublabels=set([1,2,3,4,5,6,7,8,9,10]) # All levels just as an exampleim=plt.imshow(np.linspace(0.5, 2, 100).reshape((10, 10)), norm=LogNorm(0.5, 2))
cb=plt.colorbar(format=MF())
I am using mpl 3.1.1
Any ideas? Is there another way to fix this?
The problem is that I always want to show the bottom tick, but even adding with cb.set_ticks([0.5] doesn't do anything.
PRs certainly welcome for this - someone would have to dig into the guts of the LogFormatter for minor ticks. That would be great, but it is unusual to use log scales on such a small range of data, hence it hasn't received much attention. Note the simpler minimal example is
import matplotlib.pyplot as plt
plt.xscale("log")
plt.xlim(0.25, 5)
plt.show()
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
ImportanceOfBeingErnest commented on Oct 12, 2018
At least in matplotlib 2.0.2, the resulting image is the same as shown above.
In matplotlib 1.5.3 the resulting image is
In current master, the result is
where something strange is happending with the formatting, probably the same issue as #12488.
That being said, I think having the lower end ticked and labeled if it falls on a "useful" number may be more appealing; but expectations might be different here for different cases, such that finding a good default is not obvious.
You can decide to have all minor ticks labelled (which would result in crowded axes here) or none (which would not show any label except the10^1), or, you can have "nice" labels (the default). This is hardcoded to be [1,2,3,4,6,10]*10^exp
matplotlib/lib/matplotlib/ticker.py
Line 963 in aa1e5cf
On a by-case basis you may of course use your own locations
import matplotlib.pyplot as plt import numpy as np from matplotlib.colors import LogNorm from matplotlib.ticker import LogFormatterSciNotation plt.imshow(np.random.random(15**2).reshape((15, 15))+0.5, norm=LogNorm(vmax=2, vmin=0.5), cmap='coolwarm') class MF(LogFormatterSciNotation): def set_locs(self, locs=None): self._sublabels = set([1,2,5,10]) cb = plt.colorbar(format=MF()) plt.show()Having an interface for those of the style LogFormatter(..., sublabels=None) would be an option to add. In case sublabels are provided, minor_thresholds would be ignored, and self._sublabels = sublabels being set.
jklymak commented on Oct 12, 2018
Just to clarify. On 3.0.0 the auto ticks should be the same as for any other log axis. That is a change as before colorbars drew their own ticks and labels.
ImportanceOfBeingErnest commented on Oct 12, 2018
Yep, so the problem can of course be reformulated as to whether there should be an option to customize automatic ticking in
plt.xscale("log") plt.xlim(0.5, 2)anntzer commented on Oct 12, 2018
I think @Phlya may not see the formatting (superscript vs inline math) issue because of some setting in his rcParams? @Phlya can you provide them?
Phlya commented on Oct 12, 2018
Here is my matplotlibrc, I think everything is commented out...
matplotlibrc.zip
And I also have sns.set_style("ticks") in case it might be important.
ImportanceOfBeingErnest commented on Oct 12, 2018
No, for the code shown here, the "formatting (superscript vs inline math) issue" does not appear in version 2.2.2 (which @Phlya is using). Neither in matplotlib 3.0.0. (sorry, wrong env used)
It only appears in the master branch and (edit ->) in matplotlib 3.0.0.
anntzer commented on Oct 12, 2018
I also see it with mpl3.0.0.
jklymak commented on Oct 12, 2018
This seems a reasonable feature request to me. I actually am not sure I like the defaults....
anntzer commented on Oct 13, 2018
In this specific case, it seems like the minortick labeler should just check what is the lowest minor tick and adjust itself accordingly?
Phlya commented on Nov 1, 2019
I keep stumbling upon this issue - I often use LogNorm with values around 1 in the range as used above.
I was just now trying to reproduce the custom subclass from #12503 (comment) to fix this, but it doesn't seem to work:
I am using mpl 3.1.1
Any ideas? Is there another way to fix this?
The problem is that I always want to show the bottom tick, but even adding with cb.set_ticks([0.5] doesn't do anything.
Phlya commented on Nov 1, 2019
Even more strange, perhaps, is that with vmin=0.25, vmax=4 the colorbar has no tick labels apart from 1.

jklymak commented on Nov 1, 2019
PRs certainly welcome for this - someone would have to dig into the guts of the LogFormatter for minor ticks. That would be great, but it is unusual to use log scales on such a small range of data, hence it hasn't received much attention. Note the simpler minimal example is
import matplotlib.pyplot as plt plt.xscale("log") plt.xlim(0.25, 5) plt.show()ImportanceOfBeingErnest commented on Nov 1, 2019
The workaround from above would now need to look like
import matplotlib.pyplot as plt import numpy as np from matplotlib.colors import LogNorm from matplotlib.ticker import LogFormatterSciNotation plt.imshow(np.random.random(15**2).reshape((15, 15))+0.5, norm=LogNorm(vmax=2, vmin=0.5), cmap='coolwarm') class MF(LogFormatterSciNotation): def set_locs(self, locs=None): self._sublabels = set([1,2,5,10]) cb = plt.colorbar(format=MF()) cb.ax.yaxis.set_minor_formatter(MF()) plt.show()but it's still a workaround and uses some private attribute, so a more sustainable solution is clearly desireable.
anntzer commented on Nov 2, 2019
Would be nice to figure out why #12865 doesn't help here.
github-actions commented on May 18, 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!