Skip to content

Commit fe721a6

Browse files
authored
Merge pull request #7586 from efiring/locator_doc_validate
MaxNLocator 'steps' validation; and documentation. Closes #7578.
2 parents 1b58fcd + 3d1c293 commit fe721a6

File tree

3 files changed

+39
-14
lines changed

3 files changed

+39
-14
lines changed

doc/users/dflt_style_changes.rst

+5
Original file line numberDiff line numberDiff line change
@@ -969,6 +969,11 @@ or create a new `~matplotlib.ticker.MaxNLocator`::
969969
import matplotlib.ticker as mticker
970970
ax.set_major_locator(mticker.MaxNLocator(nbins=9, steps=[1, 2, 5, 10])
971971

972+
The algorithm used by `~matplotlib.ticker.MaxNLocator` has been
973+
improved, and this may change the choice of tick locations in some
974+
cases. This also affects `~matplotlib.ticker.AutoLocator`, which
975+
uses ``MaxNLocator`` internally.
976+
972977
For a log-scaled axis the default locator is the
973978
`~matplotlib.ticker.LogLocator`. Previously the maximum number
974979
of ticks was set to 15, and could not be changed. Now there is a

lib/matplotlib/tests/test_ticker.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ def test_MaxNLocator_integer():
3232
test_value = np.array([-1, 0, 1, 2])
3333
assert_almost_equal(loc.tick_values(-0.1, 1.1), test_value)
3434

35-
test_value = np.array([-0.25, 0, 0.25, 0.5, 0.75, 1])
35+
test_value = np.array([-0.3, 0, 0.3, 0.6, 0.9, 1.2])
3636
assert_almost_equal(loc.tick_values(-0.1, 0.95), test_value)
3737

3838

lib/matplotlib/ticker.py

+33-13
Original file line numberDiff line numberDiff line change
@@ -1698,6 +1698,33 @@ def __init__(self, *args, **kwargs):
16981698
self.set_params(**self.default_params)
16991699
self.set_params(**kwargs)
17001700

1701+
@staticmethod
1702+
def _validate_steps(steps):
1703+
if not np.iterable(steps):
1704+
raise ValueError('steps argument must be a sequence of numbers '
1705+
'from 1 to 10')
1706+
steps = np.asarray(steps)
1707+
if np.any(np.diff(steps) <= 0):
1708+
raise ValueError('steps argument must be uniformly increasing')
1709+
if steps[-1] > 10 or steps[0] < 1:
1710+
warnings.warn('Steps argument should be a sequence of numbers\n'
1711+
'increasing from 1 to 10, inclusive. Behavior with\n'
1712+
'values outside this range is undefined, and will\n'
1713+
'raise a ValueError in future versions of mpl.')
1714+
if steps[0] != 1:
1715+
steps = np.hstack((1, steps))
1716+
if steps[-1] != 10:
1717+
steps = np.hstack((steps, 10))
1718+
return steps
1719+
1720+
@staticmethod
1721+
def _staircase(steps):
1722+
# Make an extended staircase within which the needed
1723+
# step will be found. This is probably much larger
1724+
# than necessary.
1725+
flights = (0.1 * steps[:-1], steps, 10 * steps[1])
1726+
return np.hstack(flights)
1727+
17011728
def set_params(self, **kwargs):
17021729
"""Set parameters within this locator."""
17031730
if 'nbins' in kwargs:
@@ -1719,23 +1746,16 @@ def set_params(self, **kwargs):
17191746
if 'steps' in kwargs:
17201747
steps = kwargs['steps']
17211748
if steps is None:
1722-
self._steps = [1, 1.5, 2, 2.5, 3, 4, 5, 6, 8, 10]
1749+
self._steps = np.array([1, 1.5, 2, 2.5, 3, 4, 5, 6, 8, 10])
17231750
else:
1724-
if int(steps[-1]) != 10:
1725-
steps = list(steps)
1726-
steps.append(10)
1727-
self._steps = steps
1728-
# Make an extended staircase within which the needed
1729-
# step will be found. This is probably much larger
1730-
# than necessary.
1731-
flights = (0.1 * np.array(self._steps[:-1]),
1732-
self._steps,
1733-
[10 * self._steps[1]])
1734-
self._extended_steps = np.hstack(flights)
1751+
self._steps = self._validate_steps(steps)
1752+
self._extended_steps = self._staircase(self._steps)
17351753
if 'integer' in kwargs:
17361754
self._integer = kwargs['integer']
17371755
if self._integer:
1738-
self._steps = [n for n in self._steps if _divmod(n, 1)[1] < 0.001]
1756+
self._steps = np.array([n for n in self._steps
1757+
if _divmod(n, 1)[1] < 0.001])
1758+
self._extended_steps = self._staircase(self._steps)
17391759
if 'min_n_ticks' in kwargs:
17401760
self._min_n_ticks = max(1, kwargs['min_n_ticks'])
17411761

0 commit comments

Comments
 (0)