Skip to content
  • Sponsor matplotlib/matplotlib

  • Notifications You must be signed in to change notification settings
  • Fork 7.9k

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
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
@@ -112,6 +112,9 @@ Ticks, tick labels and Offset text

Axis.axis_date

Axis.minorticks_off
Axis.minorticks_on


Data and view intervals
-----------------------
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
@@ -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

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