From 1706340008a57e1e80c01091738b9a0b1cad4b92 Mon Sep 17 00:00:00 2001 From: Eric Firing Date: Thu, 8 Dec 2016 10:01:26 -1000 Subject: [PATCH] LogFormatter bugfix, docs, support classic Closes #7590. Classic style, with no minor tick labeling on a log axis, is supported via rcParams['_internal.classic'] LogFormatter changes are documented in api_changes and dflt_style_changes. An implicit boolean is made explicit in scale.py. A LogFormatter attribute that was sometimes, but not always, set by set_locs, but used only in __call__, is replaced by a local variable calculated in __call__. (set_locs doesn't have to be called prior to __call__, so this would have been a bug even if the attribute were always calculated by set_locs.) --- doc/api/api_changes.rst | 10 ++++++++++ doc/users/dflt_style_changes.rst | 9 +++++++++ lib/matplotlib/scale.py | 2 +- lib/matplotlib/tests/test_ticker.py | 2 +- lib/matplotlib/ticker.py | 21 ++++++++++++++++----- 5 files changed, 37 insertions(+), 7 deletions(-) diff --git a/doc/api/api_changes.rst b/doc/api/api_changes.rst index 2f11afb16074..fdc4c20547b1 100644 --- a/doc/api/api_changes.rst +++ b/doc/api/api_changes.rst @@ -141,6 +141,16 @@ the kwarg is None which internally sets it to the 'auto' string, triggering a new algorithm for adjusting the maximum according to the axis length relative to the ticklabel font size. +`matplotlib.ticker.LogFormatter` gains minor_thresholds kwarg +------------------------------------------------------------- + +Previously, minor ticks on log-scaled axes were not labeled by +default. An algorithm has been added to the +`~matplotlib.ticker.LogFormatter` to control the labeling of +ticks between integer powers of the base. The algorithm uses +two parameters supplied in a kwarg tuple named 'minor_thresholds'. +See the docstring for further explanation. + New defaults for 3D quiver function in mpl_toolkits.mplot3d.axes3d.py --------------------------------------------------------------------- diff --git a/doc/users/dflt_style_changes.rst b/doc/users/dflt_style_changes.rst index 6e08fa4e712a..ffafc19cdfd6 100644 --- a/doc/users/dflt_style_changes.rst +++ b/doc/users/dflt_style_changes.rst @@ -1042,6 +1042,15 @@ Z-order ``rcParams['axes.axisbelow'] = False``. +``LogFormatter`` labeling of minor ticks +======================================== + +Minor ticks on a log axis are now labeled when the axis view limits +span a range less than or equal to the interval between two major +ticks. See `~matplotlib.ticker.LogFormatter` for details. The +minor tick labeling is turned off when using ``mpl.style.use('classic')``, +but cannot be controlled independently via ``rcParams``. + ``ScalarFormatter`` tick label formatting with offsets ====================================================== diff --git a/lib/matplotlib/scale.py b/lib/matplotlib/scale.py index 1a8079b05615..bad1661e39fe 100644 --- a/lib/matplotlib/scale.py +++ b/lib/matplotlib/scale.py @@ -251,7 +251,7 @@ def set_default_locators_and_formatters(self, axis): axis.set_minor_locator(LogLocator(self.base, self.subs)) axis.set_minor_formatter( LogFormatterSciNotation(self.base, - labelOnlyBase=self.subs)) + labelOnlyBase=bool(self.subs))) def get_transform(self): """ diff --git a/lib/matplotlib/tests/test_ticker.py b/lib/matplotlib/tests/test_ticker.py index e60ba93276ac..19f753ee188f 100644 --- a/lib/matplotlib/tests/test_ticker.py +++ b/lib/matplotlib/tests/test_ticker.py @@ -231,7 +231,7 @@ def _sub_labels(axis, subs=()): assert_equal(label_test, label_expected) -@cleanup +@cleanup(style='default') def test_LogFormatter_sublabel(): # test label locator fig, ax = plt.subplots() diff --git a/lib/matplotlib/ticker.py b/lib/matplotlib/ticker.py index 754f2158159d..fdb21b5f5df6 100644 --- a/lib/matplotlib/ticker.py +++ b/lib/matplotlib/ticker.py @@ -837,7 +837,12 @@ class LogFormatter(Formatter): major and minor ticks; the tick locations might be set manually, or by a locator that puts ticks at integer powers of base and at intermediate locations. For this situation, disable the - minor_thresholds logic by using ``minor_thresholds=(np.inf, np.inf)``. + minor_thresholds logic by using ``minor_thresholds=(np.inf, np.inf)``, + so that all ticks will be labeled. + + To disable labeling of minor ticks when 'labelOnlyBase' is False, + use ``minor_thresholds=(0, 0)``. This is the default for the + "classic" style. Examples -------- @@ -848,14 +853,18 @@ class LogFormatter(Formatter): To label all minor ticks when the view limits span up to 1.5 decades, use ``minor_thresholds=(1.5, 1.5)``. - """ def __init__(self, base=10.0, labelOnlyBase=False, - minor_thresholds=(1, 0.4), + minor_thresholds=None, linthresh=None): self._base = float(base) self.labelOnlyBase = labelOnlyBase + if minor_thresholds is None: + if rcParams['_internal.classic_mode']: + minor_thresholds = (0, 0) + else: + minor_thresholds = (1, 0.4) self.minor_thresholds = minor_thresholds self._sublabels = None self._linthresh = linthresh @@ -896,7 +905,6 @@ def set_locs(self, locs=None): b = self._base vmin, vmax = self.axis.get_view_interval() - self.d = abs(vmax - vmin) # Handle symlog case: linthresh = self._linthresh @@ -937,6 +945,9 @@ def __call__(self, x, pos=None): """ Return the format for tick val `x`. """ + vmin, vmax = self.axis.get_view_interval() + vmin, vmax = mtransforms.nonsingular(vmin, vmax, expander=0.05) + d = abs(vmax - vmin) b = self._base if x == 0.0: return '0' @@ -957,7 +968,7 @@ def __call__(self, x, pos=None): elif x < 1: s = '%1.0e' % x else: - s = self.pprint_val(x, self.d) + s = self.pprint_val(x, d) if sign == -1: s = '-%s' % s