diff --git a/doc/api/axis_api.rst b/doc/api/axis_api.rst index a177f82a4a9a..17e892b99df8 100644 --- a/doc/api/axis_api.rst +++ b/doc/api/axis_api.rst @@ -112,6 +112,9 @@ Ticks, tick labels and Offset text Axis.axis_date + Axis.minorticks_off + Axis.minorticks_on + Data and view intervals ----------------------- diff --git a/doc/users/next_whats_new/axis_minorticks_toggle.rst b/doc/users/next_whats_new/axis_minorticks_toggle.rst new file mode 100644 index 000000000000..bb6545e5cb4c --- /dev/null +++ b/doc/users/next_whats_new/axis_minorticks_toggle.rst @@ -0,0 +1,6 @@ +Toggle minorticks on Axis +------------------------------ + +Minor ticks on an `~matplotlib.axis.Axis` can be displayed or removed using +`~matplotlib.axis.Axis.minorticks_on` and `~matplotlib.axis.Axis.minorticks_off`; +e.g.: ``ax.xaxis.minorticks_on()``. See also `~matplotlib.axes.Axes.minorticks_on`. diff --git a/lib/matplotlib/axes/_base.py b/lib/matplotlib/axes/_base.py index 5d612c581270..be0aacd81bb0 100644 --- a/lib/matplotlib/axes/_base.py +++ b/lib/matplotlib/axes/_base.py @@ -3987,22 +3987,13 @@ def minorticks_on(self): Displaying minor ticks may reduce performance; you may turn them off using `minorticks_off()` if drawing speed is a problem. """ - for ax in (self.xaxis, self.yaxis): - scale = ax.get_scale() - if scale == 'log': - s = ax._scale - ax.set_minor_locator(mticker.LogLocator(s.base, s.subs)) - elif scale == 'symlog': - s = ax._scale - ax.set_minor_locator( - mticker.SymmetricalLogLocator(s._transform, s.subs)) - else: - ax.set_minor_locator(mticker.AutoMinorLocator()) + self.xaxis.minorticks_on() + self.yaxis.minorticks_on() def minorticks_off(self): """Remove minor ticks from the Axes.""" - self.xaxis.set_minor_locator(mticker.NullLocator()) - self.yaxis.set_minor_locator(mticker.NullLocator()) + self.xaxis.minorticks_off() + self.yaxis.minorticks_off() # Interactive manipulation diff --git a/lib/matplotlib/axis.py b/lib/matplotlib/axis.py index dbd65aba4a17..d317f6ec0567 100644 --- a/lib/matplotlib/axis.py +++ b/lib/matplotlib/axis.py @@ -928,6 +928,44 @@ def reset_ticks(self): except AttributeError: pass + def minorticks_on(self): + """ + Display default minor ticks on the Axis, depending on the scale + (`~.axis.Axis.get_scale`). + + Scales use specific minor locators: + + - log: `~.LogLocator` + - symlog: `~.SymmetricalLogLocator` + - asinh: `~.AsinhLocator` + - logit: `~.LogitLocator` + - default: `~.AutoMinorLocator` + + Displaying minor ticks may reduce performance; you may turn them off + using `minorticks_off()` if drawing speed is a problem. + """ + scale = self.get_scale() + if scale == 'log': + s = self._scale + self.set_minor_locator(mticker.LogLocator(s.base, s.subs)) + elif scale == 'symlog': + s = self._scale + self.set_minor_locator( + mticker.SymmetricalLogLocator(s._transform, s.subs)) + elif scale == 'asinh': + s = self._scale + self.set_minor_locator( + mticker.AsinhLocator(s.linear_width, base=s._base, + subs=s._subs)) + elif scale == 'logit': + self.set_minor_locator(mticker.LogitLocator(minor=True)) + else: + self.set_minor_locator(mticker.AutoMinorLocator()) + + def minorticks_off(self): + """Remove minor ticks from the Axis.""" + self.set_minor_locator(mticker.NullLocator()) + def set_tick_params(self, which='major', reset=False, **kwargs): """ Set appearance parameters for ticks, ticklabels, and gridlines. diff --git a/lib/matplotlib/axis.pyi b/lib/matplotlib/axis.pyi index 5ca8fcb6fd6c..e23ae381c338 100644 --- a/lib/matplotlib/axis.pyi +++ b/lib/matplotlib/axis.pyi @@ -151,6 +151,8 @@ class Axis(martist.Artist): units: Any def clear(self) -> None: ... def reset_ticks(self) -> None: ... + def minorticks_on(self) -> None: ... + def minorticks_off(self) -> None: ... def set_tick_params( self, which: Literal["major", "minor", "both"] = ..., diff --git a/lib/matplotlib/tests/test_ticker.py b/lib/matplotlib/tests/test_ticker.py index 0cd9cfd9ad77..565f32105cea 100644 --- a/lib/matplotlib/tests/test_ticker.py +++ b/lib/matplotlib/tests/test_ticker.py @@ -1734,6 +1734,46 @@ def minorticksubplot(xminor, yminor, i): minorticksubplot(True, True, 4) +def test_minorticks_toggle(): + """ + Test toggling minor ticks + + Test `.Axis.minorticks_on()` and `.Axis.minorticks_off()`. Testing is + limited to a subset of built-in scales - `'linear'`, `'log'`, `'asinh'` + and `'logit'`. `symlog` scale does not seem to have a working minor + locator and is omitted. In future, this test should cover all scales in + `matplotlib.scale.get_scale_names()`. + """ + fig = plt.figure() + def minortickstoggle(xminor, yminor, scale, i): + ax = fig.add_subplot(2, 2, i) + ax.set_xscale(scale) + ax.set_yscale(scale) + if not xminor and not yminor: + ax.minorticks_off() + if xminor and not yminor: + ax.xaxis.minorticks_on() + ax.yaxis.minorticks_off() + if not xminor and yminor: + ax.xaxis.minorticks_off() + ax.yaxis.minorticks_on() + if xminor and yminor: + ax.minorticks_on() + + assert (len(ax.xaxis.get_minor_ticks()) > 0) == xminor + assert (len(ax.yaxis.get_minor_ticks()) > 0) == yminor + + scales = ['linear', 'log', 'asinh', 'logit'] + for scale in scales: + minortickstoggle(False, False, scale, 1) + minortickstoggle(True, False, scale, 2) + minortickstoggle(False, True, scale, 3) + minortickstoggle(True, True, scale, 4) + fig.clear() + + plt.close(fig) + + @pytest.mark.parametrize('remove_overlapping_locs, expected_num', ((True, 6), (None, 6), # this tests the default