Skip to content

FIX: LogFormatter minor ticks with minor_thresholds of (0,0) misbehaves #26277

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

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
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
4 changes: 2 additions & 2 deletions lib/matplotlib/scale.py
Original file line number Diff line number Diff line change
Expand Up @@ -288,7 +288,7 @@ def __init__(self, axis, *, base=10, subs=None, nonpositive="clip"):
def set_default_locators_and_formatters(self, axis):
# docstring inherited
axis.set_major_locator(LogLocator(self.base))
axis.set_major_formatter(LogFormatterSciNotation(self.base))
axis.set_major_formatter(LogFormatterSciNotation(self.base, labelOnlyBase=True))
axis.set_minor_locator(LogLocator(self.base, self.subs))
axis.set_minor_formatter(
LogFormatterSciNotation(self.base,
Expand Down Expand Up @@ -451,7 +451,7 @@ def __init__(self, axis, *, base=10, linthresh=2, subs=None, linscale=1):
def set_default_locators_and_formatters(self, axis):
# docstring inherited
axis.set_major_locator(SymmetricalLogLocator(self.get_transform()))
axis.set_major_formatter(LogFormatterSciNotation(self.base))
axis.set_major_formatter(LogFormatterSciNotation(self.base, labelOnlyBase=True))
axis.set_minor_locator(SymmetricalLogLocator(self.get_transform(),
self.subs))
axis.set_minor_formatter(NullFormatter())
Expand Down
16 changes: 16 additions & 0 deletions lib/matplotlib/tests/test_ticker.py
Original file line number Diff line number Diff line change
Expand Up @@ -1155,6 +1155,13 @@ def _sub_labels(self, axis, subs=()):
label_test = [fmt(x) != '' for x in minor_tlocs]
assert label_test == label_expected

def _no_minor_labels(self, axis):
fmt = axis.get_minor_formatter()
minor_tlocs = axis.get_minorticklocs()
fmt.set_locs(minor_tlocs)
label_test = [fmt(x) == '' for x in minor_tlocs]
assert all(label_test)

@mpl.style.context('default')
def test_sublabel(self):
# test label locator
Expand Down Expand Up @@ -1193,6 +1200,15 @@ def test_sublabel(self):
ax.set_xlim(0.5, 0.9)
self._sub_labels(ax.xaxis, subs=np.arange(2, 10, dtype=int))

# minor_thresholds=(0, 0), no minor tick will be labeled
ax.xaxis.set_minor_formatter(
mticker.LogFormatter(
labelOnlyBase=False,
minor_thresholds=(0, 0)
)
)
self._no_minor_labels(ax.xaxis)

@pytest.mark.parametrize('val', [1, 10, 100, 1000])
def test_LogFormatter_call(self, val):
# test _num_to_string method used in __call__
Expand Down
18 changes: 10 additions & 8 deletions lib/matplotlib/ticker.py
Original file line number Diff line number Diff line change
Expand Up @@ -952,8 +952,8 @@ def set_locs(self, locs=None):
numdec = abs(vmax - vmin)

if numdec > self.minor_thresholds[0]:
# Label only bases
self._sublabels = {1}
# No minor ticks will be labeled
self._sublabels = {}
elif numdec > self.minor_thresholds[1]:
# Add labels between bases at log-spaced coefficients;
# include base powers in case the locations include
Expand Down Expand Up @@ -987,9 +987,10 @@ def __call__(self, x, pos=None):
exponent = round(fx) if is_x_decade else np.floor(fx)
coeff = round(b ** (fx - exponent))

if self.labelOnlyBase and not is_x_decade:
return ''
if self._sublabels is not None and coeff not in self._sublabels:
if self.labelOnlyBase:
if not is_x_decade:
return ''
elif self._sublabels is not None and coeff not in self._sublabels:
return ''

vmin, vmax = self.axis.get_view_interval()
Expand Down Expand Up @@ -1073,9 +1074,10 @@ def __call__(self, x, pos=None):
if is_x_decade:
fx = round(fx)

if self.labelOnlyBase and not is_x_decade:
return ''
if self._sublabels is not None and coeff not in self._sublabels:
if self.labelOnlyBase:
if not is_x_decade:
return ''
elif self._sublabels is not None and coeff not in self._sublabels:
return ''

# use string formatting of the base if it is not an integer
Expand Down