From d12a00e2c581bf058ef003afb0cde5d80c89c682 Mon Sep 17 00:00:00 2001 From: Eric Firing Date: Sun, 8 Jan 2017 16:11:22 -1000 Subject: [PATCH] BUG: improve integer step selection in MaxNLocator MaxNLocator with integer=True was unnecessarily restricting the possible steps. The restriction to integers is now done after scaling, not before. --- lib/matplotlib/tests/test_ticker.py | 6 +++++- lib/matplotlib/ticker.py | 13 +++++++------ 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/lib/matplotlib/tests/test_ticker.py b/lib/matplotlib/tests/test_ticker.py index 75cad9f27730..159379b27c27 100644 --- a/lib/matplotlib/tests/test_ticker.py +++ b/lib/matplotlib/tests/test_ticker.py @@ -32,9 +32,13 @@ def test_MaxNLocator_integer(): test_value = np.array([-1, 0, 1, 2]) assert_almost_equal(loc.tick_values(-0.1, 1.1), test_value) - test_value = np.array([-0.3, 0, 0.3, 0.6, 0.9, 1.2]) + test_value = np.array([-0.25, 0, 0.25, 0.5, 0.75, 1.0]) assert_almost_equal(loc.tick_values(-0.1, 0.95), test_value) + loc = mticker.MaxNLocator(nbins=5, integer=True, steps=[1, 1.5, 5, 6, 10]) + test_value = np.array([0, 15, 30, 45, 60]) + assert_almost_equal(loc.tick_values(1, 55), test_value) + def test_LinearLocator(): loc = mticker.LinearLocator(numticks=3) diff --git a/lib/matplotlib/ticker.py b/lib/matplotlib/ticker.py index 2278c33eb3c8..34120bad6716 100644 --- a/lib/matplotlib/ticker.py +++ b/lib/matplotlib/ticker.py @@ -1836,6 +1836,8 @@ def set_params(self, **kwargs): raise ValueError( "prune must be 'upper', 'lower', 'both', or None") self._prune = prune + if 'min_n_ticks' in kwargs: + self._min_n_ticks = max(1, kwargs['min_n_ticks']) if 'steps' in kwargs: steps = kwargs['steps'] if steps is None: @@ -1845,12 +1847,6 @@ def set_params(self, **kwargs): self._extended_steps = self._staircase(self._steps) if 'integer' in kwargs: self._integer = kwargs['integer'] - if self._integer: - self._steps = np.array([n for n in self._steps - if _divmod(n, 1)[1] < 0.001]) - self._extended_steps = self._staircase(self._steps) - if 'min_n_ticks' in kwargs: - self._min_n_ticks = max(1, kwargs['min_n_ticks']) def _raw_ticks(self, vmin, vmax): if self._nbins == 'auto': @@ -1867,6 +1863,11 @@ def _raw_ticks(self, vmin, vmax): _vmax = vmax - offset raw_step = (vmax - vmin) / nbins steps = self._extended_steps * scale + if self._integer: + # For steps > 1, keep only integer values. + igood = (steps < 1) | (np.abs(steps - np.round(steps)) < 0.001) + steps = steps[igood] + istep = np.nonzero(steps >= raw_step)[0][0] # Classic round_numbers mode may require a larger step.