Thanks to visit codestin.com
Credit goes to github.com

Skip to content

WARN: more direct warning ticklabels #26401

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
Aug 3, 2023
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
29 changes: 20 additions & 9 deletions lib/matplotlib/axis.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import functools
import logging
from numbers import Real
import warnings

import numpy as np

Expand Down Expand Up @@ -1965,7 +1966,10 @@ def set_ticklabels(self, labels, *, minor=False, fontdict=None, **kwargs):
raise TypeError(f"{labels:=} must be a sequence") from None
locator = (self.get_minor_locator() if minor
else self.get_major_locator())
if isinstance(locator, mticker.FixedLocator):
if not labels:
# eg labels=[]:
formatter = mticker.NullFormatter()
Copy link
Member

@timhoffm timhoffm Jul 30, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This does not have an effect if you return on the next line. formatter is only used in lines 2005ff.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Obviously, this is untested. You can add a test that there is no warning using

with warnings.catch_warnings():
    warnings.simplefilter("error")

https://docs.pytest.org/en/7.0.x/how-to/capture-warnings.html#additional-use-cases-of-warnings-in-tests

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oops thanks I knew there was a reason to not do that.

It is tested, but the old code ends up being used

I'll move to draft as I'm away for a few days

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the warning filter necessary, since we run with warnings as errors in general? C.f. the test added at #26300.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not necessary but prevents the same warning appearing with two different syntaxes.

elif isinstance(locator, mticker.FixedLocator):
# Passing [] as a list of labels is often used as a way to
# remove all tick labels, so only error for > 0 labels
if len(locator.locs) != len(labels) and len(labels) != 0:
Expand All @@ -1978,16 +1982,23 @@ def set_ticklabels(self, labels, *, minor=False, fontdict=None, **kwargs):
func = functools.partial(self._format_with_dict, tickd)
formatter = mticker.FuncFormatter(func)
else:
_api.warn_external(
"set_ticklabels() should only be used with a fixed number of "
"ticks, i.e. after set_ticks() or using a FixedLocator.")
formatter = mticker.FixedFormatter(labels)

if minor:
self.set_minor_formatter(formatter)
locs = self.get_minorticklocs()
ticks = self.get_minor_ticks(len(locs))
else:
self.set_major_formatter(formatter)
locs = self.get_majorticklocs()
ticks = self.get_major_ticks(len(locs))
with warnings.catch_warnings():
warnings.filterwarnings(
"ignore",
message="FixedFormatter should only be used together with FixedLocator")
if minor:
self.set_minor_formatter(formatter)
locs = self.get_minorticklocs()
ticks = self.get_minor_ticks(len(locs))
else:
self.set_major_formatter(formatter)
locs = self.get_majorticklocs()
ticks = self.get_major_ticks(len(locs))

ret = []
if fontdict is not None:
Expand Down
15 changes: 15 additions & 0 deletions lib/matplotlib/tests/test_axes.py
Original file line number Diff line number Diff line change
Expand Up @@ -6063,6 +6063,21 @@ def test_retain_tick_visibility():
ax.tick_params(axis="y", which="both", length=0)


def test_warn_too_few_labels():
# note that the axis is still using an AutoLocator:
fig, ax = plt.subplots()
with pytest.warns(
UserWarning,
match=r'set_ticklabels\(\) should only be used with a fixed number'):
ax.set_xticklabels(['0', '0.1'])
# note that the axis is still using a FixedLocator:
fig, ax = plt.subplots()
ax.set_xticks([0, 0.5, 1])
with pytest.raises(ValueError,
match='The number of FixedLocator locations'):
ax.set_xticklabels(['0', '0.1'])


def test_tick_label_update():
# test issue 9397

Expand Down