Skip to content

Add minor ticks on and off in Axis #22761

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Mar 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions doc/api/axis_api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,9 @@ Ticks, tick labels and Offset text

Axis.axis_date

Axis.minorticks_off
Axis.minorticks_on


Data and view intervals
-----------------------
Expand Down
6 changes: 6 additions & 0 deletions doc/users/next_whats_new/axis_minorticks_toggle.rst
Original file line number Diff line number Diff line change
@@ -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`.
17 changes: 4 additions & 13 deletions lib/matplotlib/axes/_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
38 changes: 38 additions & 0 deletions lib/matplotlib/axis.py
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
2 changes: 2 additions & 0 deletions lib/matplotlib/axis.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -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"] = ...,
Expand Down
40 changes: 40 additions & 0 deletions lib/matplotlib/tests/test_ticker.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down