Skip to content

Commit 58e3432

Browse files
committed
FIX: try hard to ensure at least 2 ticks with 'auto'
This requires falling back on a larger set of options for intervals between ticks. Closes #5784.
1 parent 46d6e6c commit 58e3432

File tree

1 file changed

+35
-9
lines changed

1 file changed

+35
-9
lines changed

lib/matplotlib/ticker.py

+35-9
Original file line numberDiff line numberDiff line change
@@ -1619,6 +1619,8 @@ def __init__(self, *args, **kwargs):
16191619
will be removed. If prune==None, no ticks will be removed.
16201620
16211621
"""
1622+
self._fine_steps = [1, 1.5, 2, 2.5, 3, 4, 5, 6, 8, 10]
1623+
self._fine_int_steps = [1, 2, 3, 4, 5, 6, 8, 10]
16221624
if args:
16231625
kwargs['nbins'] = args[0]
16241626
if len(args) > 1:
@@ -1631,8 +1633,11 @@ def set_params(self, **kwargs):
16311633
"""Set parameters within this locator."""
16321634
if 'nbins' in kwargs:
16331635
self._nbins = kwargs['nbins']
1634-
if self._nbins != 'auto':
1635-
self._nbins = int(self._nbins)
1636+
if self._nbins != 'auto':
1637+
self._nbins = int(self._nbins)
1638+
self._steps2 = None
1639+
else:
1640+
self._steps2 = self._fine_steps
16361641
if 'trim' in kwargs:
16371642
warnings.warn(
16381643
"The 'trim' keyword has no effect since version 2.0.",
@@ -1650,7 +1655,8 @@ def set_params(self, **kwargs):
16501655
if 'steps' in kwargs:
16511656
steps = kwargs['steps']
16521657
if steps is None:
1653-
self._steps = [1, 1.5, 2, 2.5, 3, 4, 5, 6, 8, 10]
1658+
self._steps = self._fine_steps
1659+
self._steps2 = None
16541660
else:
16551661
if int(steps[-1]) != 10:
16561662
steps = list(steps)
@@ -1660,11 +1666,19 @@ def set_params(self, **kwargs):
16601666
self._integer = kwargs['integer']
16611667
if self._integer:
16621668
self._steps = [n for n in self._steps if _divmod(n, 1)[1] < 0.001]
1669+
if self._steps2 is not None:
1670+
self._steps2 = self._fine_int_steps
16631671

1664-
def _raw_ticks(self, vmin, vmax):
1672+
def _raw_ticks(self, vmin, vmax, steps=None):
1673+
if steps is None:
1674+
steps = self._steps
16651675
nbins = self._nbins
16661676
if nbins == 'auto':
1667-
nbins = max(min(self.axis.get_tick_space(), 9), 1)
1677+
if (rcParams['axes.autolimit_mode'] == 'round_numbers'
1678+
and self._prune is None):
1679+
nbins = max(min(self.axis.get_tick_space(), 9), 2)
1680+
else:
1681+
nbins = max(min(self.axis.get_tick_space(), 9), 4)
16681682
scale, offset = scale_range(vmin, vmax, nbins)
16691683
if self._integer:
16701684
scale = max(1, scale)
@@ -1675,20 +1689,24 @@ def _raw_ticks(self, vmin, vmax):
16751689
best_vmax = vmax
16761690
best_vmin = vmin
16771691

1678-
for step in self._steps:
1692+
for step in steps:
16791693
if step < scaled_raw_step:
16801694
continue
16811695
step *= scale
1682-
best_vmin = vmin // step * step
1696+
best_vmin = (vmin // step) * step
16831697
best_vmax = best_vmin + step * nbins
16841698
if best_vmax >= vmax:
16851699
break
16861700

16871701
# More than nbins may be required, e.g. vmin, vmax = -4.1, 4.1 gives
16881702
# nbins=9 but 10 bins are actually required after rounding. So we just
16891703
# create the bins that span the range we need instead.
1690-
low = round(Base(step).le(vmin - best_vmin) / step)
1691-
high = round(Base(step).ge(vmax - best_vmin) / step)
1704+
if rcParams['axes.autolimit_mode'] == 'round_numbers':
1705+
low = round(Base(step).le(vmin - best_vmin) / step)
1706+
high = round(Base(step).ge(vmax - best_vmin) / step)
1707+
else:
1708+
low = round(Base(step).ge(vmin - best_vmin) / step)
1709+
high = round(Base(step).le(vmax - best_vmin) / step)
16921710
return np.arange(low, high + 1) * step + best_vmin + offset
16931711

16941712
@cbook.deprecated("2.0")
@@ -1703,7 +1721,15 @@ def tick_values(self, vmin, vmax):
17031721
vmin, vmax = mtransforms.nonsingular(
17041722
vmin, vmax, expander=1e-13, tiny=1e-14)
17051723
locs = self._raw_ticks(vmin, vmax)
1724+
locs = [loc for loc in locs if vmax >= loc >= vmin]
1725+
nlocs = len(locs)
17061726
prune = self._prune
1727+
if prune in ('lower', 'upper'):
1728+
nlocs -= 1
1729+
elif prune == 'both':
1730+
nlocs -= 2
1731+
if self._steps2 and nlocs < 2:
1732+
locs = self._raw_ticks(vmin, vmax, self._steps2)
17071733
if prune == 'lower':
17081734
locs = locs[1:]
17091735
elif prune == 'upper':

0 commit comments

Comments
 (0)