Tested with matplotlib 1.4.3 and 1.5.3 built from sources - python 2.7.11 - Windows and Linux (64-bit)
To reproduce this issue, choose a set of values X so that -100<X<-10, then plot a NonUniformImage and attach a colorbar with a SymmetricalLogLocator : no tick or ticklabel will be displayed on the colorbar.
The attached patch allows to draw ticks/ticklabels in case no decade (or only one) was selected based on vmin/vmax detected values.
There is however still an issue in the colorbar height.
Index: lib/matplotlib/colorbar.py
===================================================================
--- lib/matplotlib/colorbar.py (revision 97805)
+++ lib/matplotlib/colorbar.py (working copy)
@@ -592,12 +592,14 @@
formatter.set_data_interval(*intv)
b = np.array(locator())
- if isinstance(locator, ticker.LogLocator):
+ if isinstance(locator, ticker.LogLocator) or isinstance(locator, ticker.SymmetricalLogLocator):
eps = 1e-10
b = b[(b <= intv[1] * (1 + eps)) & (b >= intv[0] * (1 - eps))]
else:
eps = (intv[1] - intv[0]) * 1e-10
b = b[(b <= intv[1] + eps) & (b >= intv[0] - eps)]
+ if len(b)<2:
+ b = np.array(locator())
ticks = self._locate(b)
formatter.set_locs(b)
ticklabels = [formatter(t, i) for i, t in enumerate(b)]
Index: lib/matplotlib/ticker.py
===================================================================
--- lib/matplotlib/ticker.py (revision 97805)
+++ lib/matplotlib/ticker.py (working copy)
@@ -1722,6 +1722,8 @@
a_range = get_log_range(t, -vmin + 1)
else:
a_range = get_log_range(-vmax, -vmin + 1)
+ if vmin<0 and vmax<0:
+ a_range = ( a_range[0], a_range[1]+1 )
else:
a_range = (0, 0)
Following monday's discussion, I've ran some tests. By default, Log formatter behave extremely poorly with colorbars. The current behaviour is as follows
Disabling labelOnlyBase does not change anything:
Disabling the sublabels only feature (introduced in august) does not change anything:
To have a behaviour that seems reasonable for colorbars we need to modify both the sublabels filtering and the labelOnlyBase:
From our discussion, I undersand that the labelOnlyBase=True is mostly use for minor ticks. I propose to change the default to have labelOnlyBase = False to remove or disable the sublabel filtering by default. I have yet to find a case where this new filtering improved the readibility of the figure, and I believe this may be due to improvements in the defaults of max number of ticks and placements of those ticks.
Activity
egaudry commented on Sep 30, 2016
The attached patch allows to draw ticks/ticklabels in case no decade (or only one) was selected based on vmin/vmax detected values.
There is however still an issue in the colorbar height.
Index: lib/matplotlib/colorbar.py =================================================================== --- lib/matplotlib/colorbar.py (revision 97805) +++ lib/matplotlib/colorbar.py (working copy) @@ -592,12 +592,14 @@ formatter.set_data_interval(*intv) b = np.array(locator()) - if isinstance(locator, ticker.LogLocator): + if isinstance(locator, ticker.LogLocator) or isinstance(locator, ticker.SymmetricalLogLocator): eps = 1e-10 b = b[(b <= intv[1] * (1 + eps)) & (b >= intv[0] * (1 - eps))] else: eps = (intv[1] - intv[0]) * 1e-10 b = b[(b <= intv[1] + eps) & (b >= intv[0] - eps)] + if len(b)<2: + b = np.array(locator()) ticks = self._locate(b) formatter.set_locs(b) ticklabels = [formatter(t, i) for i, t in enumerate(b)] Index: lib/matplotlib/ticker.py =================================================================== --- lib/matplotlib/ticker.py (revision 97805) +++ lib/matplotlib/ticker.py (working copy) @@ -1722,6 +1722,8 @@ a_range = get_log_range(t, -vmin + 1) else: a_range = get_log_range(-vmax, -vmin + 1) + if vmin<0 and vmax<0: + a_range = ( a_range[0], a_range[1]+1 ) else: a_range = (0, 0)egaudry commented on Sep 30, 2016
might be linked to #7146
tacaswell commented on Oct 3, 2016
@egaudry Can you open a pull request with that patch?
attn @efiring
NelleV commented on Oct 24, 2016
tacaswell commented on Oct 31, 2016
NelleV commented on Oct 31, 2016
So… The behaviour is not the same for log and symlog Norm… minorticks appear with symlog but not log.
I'll do more tests.
NelleV commented on Nov 5, 2016
@efiring @tacaswell @dopplershift
Following monday's discussion, I've ran some tests. By default, Log formatter behave extremely poorly with colorbars. The current behaviour is as follows
Disabling labelOnlyBase does not change anything:

Disabling the sublabels only feature (introduced in august) does not change anything:
To have a behaviour that seems reasonable for colorbars we need to modify both the sublabels filtering and the labelOnlyBase:
Now going to using the LogFormatter on a log scaled plot while disabling the sublabels filtering does not change anything on this example: http://matplotlib.org/devdocs/examples/scales/scales.html
With sublabels:

Without sublabels:

From our discussion, I undersand that the labelOnlyBase=True is mostly use for minor ticks. I propose to change the default to have labelOnlyBase = False to remove or disable the sublabel filtering by default. I have yet to find a case where this new filtering improved the readibility of the figure, and I believe this may be due to improvements in the defaults of max number of ticks and placements of those ticks.
I have to tweak matplotlib's code to add an option to disable the sublabels, that you can find in https://github.com/NelleV/matplotlib/tree/test_7202
But here are some tests scripts I wrote:
1. Colorbars
2. the scales example
3. some random tests
NelleV commented on Nov 5, 2016
Note that by default, labelOnlyBase is True for LogFormatter but False for LogFormatterSciNotation.