diff --git a/lib/matplotlib/tests/baseline_images/test_axes/auto_numticks_log.png b/lib/matplotlib/tests/baseline_images/test_axes/auto_numticks_log.png new file mode 100644 index 000000000000..248fb669c56a Binary files /dev/null and b/lib/matplotlib/tests/baseline_images/test_axes/auto_numticks_log.png differ diff --git a/lib/matplotlib/tests/test_axes.py b/lib/matplotlib/tests/test_axes.py index 737cff66647c..d4ba30e59d12 100644 --- a/lib/matplotlib/tests/test_axes.py +++ b/lib/matplotlib/tests/test_axes.py @@ -4418,9 +4418,19 @@ def test_adjust_numtick_aspect(): @image_comparison(baseline_images=["auto_numticks"], style='default', extensions=['png']) def test_auto_numticks(): + # Make tiny, empty subplots, verify that there are only 3 ticks. fig, axes = plt.subplots(4, 4) +@image_comparison(baseline_images=["auto_numticks_log"], style='default', + extensions=['png']) +def test_auto_numticks_log(): + # Verify that there are not too many ticks with a large log range. + fig, ax = plt.subplots() + matplotlib.rcParams['axes.autolimit_mode'] = 'round_numbers' + ax.loglog([1e-20, 1e5], [1e-16, 10]) + + @cleanup def test_broken_barh_empty(): fig, ax = plt.subplots() diff --git a/lib/matplotlib/ticker.py b/lib/matplotlib/ticker.py index 02109e8bd991..ff0a71d156d2 100644 --- a/lib/matplotlib/ticker.py +++ b/lib/matplotlib/ticker.py @@ -1639,8 +1639,11 @@ def set_params(self, **kwargs): def _raw_ticks(self, vmin, vmax): if self._nbins == 'auto': - nbins = max(min(self.axis.get_tick_space(), 9), - max(1, self._min_n_ticks - 1)) + if self.axis is not None: + nbins = max(min(self.axis.get_tick_space(), 9), + max(1, self._min_n_ticks - 1)) + else: + nbins = 9 else: nbins = self._nbins @@ -1757,15 +1760,19 @@ class LogLocator(Locator): Determine the tick locations for log axes """ - def __init__(self, base=10.0, subs=(1.0,), numdecs=4, numticks=15): + def __init__(self, base=10.0, subs=(1.0,), numdecs=4, numticks=None): """ place ticks on the location= base**i*subs[j] """ + if numticks is None: + if rcParams['_internal.classic_mode']: + numticks = 15 + else: + numticks = 'auto' self.base(base) self.subs(subs) - # this needs to be validated > 1 with traitlets - self.numticks = numticks self.numdecs = numdecs + self.numticks = numticks def set_params(self, base=None, subs=None, numdecs=None, numticks=None): """Set parameters within this locator.""" @@ -1786,7 +1793,7 @@ def base(self, base): def subs(self, subs): """ - set the minor ticks the log scaling every base**i*subs[j] + set the minor ticks for the log scaling every base**i*subs[j] """ if subs is None: self._subs = None # autosub @@ -1799,6 +1806,14 @@ def __call__(self): return self.tick_values(vmin, vmax) def tick_values(self, vmin, vmax): + if self.numticks == 'auto': + if self.axis is not None: + numticks = max(min(self.axis.get_tick_space(), 9), 2) + else: + numticks = 9 + else: + numticks = self.numticks + b = self._base # dummy axis has no axes attribute if hasattr(self.axis, 'axes') and self.axis.axes.name == 'polar': @@ -1836,12 +1851,14 @@ def tick_values(self, vmin, vmax): subs = self._subs stride = 1 - if not self.numticks > 1: - raise RuntimeError('The number of ticks must be greater than 1 ' - 'for LogLocator.') - # FIXME: The following was designed for integer division in py2. - while numdec / stride + 1 > self.numticks: - stride += 1 + + if rcParams['_internal.classic_mode']: + # Leave the bug left over from the PY2-PY3 transition. + while numdec / stride + 1 > numticks: + stride += 1 + else: + while numdec // stride + 1 > numticks: + stride += 1 decades = np.arange(math.floor(vmin) - stride, math.ceil(vmax) + 2 * stride, stride)
Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.
Alternative Proxies: