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

Skip to content

ax.set_xticklabels([]) for categorical plots is broken in 3.3.0rc1 #17736

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

Closed
MaozGelbart opened this issue Jun 23, 2020 · 7 comments · Fixed by #17784
Closed

ax.set_xticklabels([]) for categorical plots is broken in 3.3.0rc1 #17736

MaozGelbart opened this issue Jun 23, 2020 · 7 comments · Fixed by #17784
Labels
API: changes Release critical For bugs that make the library unusable (segfaults, incorrect plots, etc) and major regressions.
Milestone

Comments

@MaozGelbart
Copy link
Contributor

Bug report

Bug summary

#17266 requires tick labels set by FixedFormatter to be equal to the ticks set by FixedLocator. FixedLocator is used in many cases where categorical data is plotted, e.g. bar and box plot. A way of removing all tick labels (while maintaining ticks and gridlines) is to do ax.set_xticklabels([]) or ax.set_yticklabels([]), by passing just an empty list. This works on 3.2.2, but raises a ValueError with 3.3.0rc1.

The new behavior is not mentioned in the "What's new?" section of 3.3.0rc1. I suspect this may break existing code, as it broke seaborn and this stackoverflow thread seems very popular.

Code for reproduction

# Example modified from bar example page

import matplotlib.pyplot as plt
import numpy as np

labels = ['G1', 'G2', 'G3', 'G4', 'G5']
men_means = [20, 34, 30, 35, 27]
women_means = [25, 32, 34, 20, 25]

x = np.arange(len(labels))  # the label locations
width = 0.35  # the width of the bars

fig, ax = plt.subplots()
rects1 = ax.bar(x - width/2, men_means, width, label='Men')
rects2 = ax.bar(x + width/2, women_means, width, label='Women')

ax.set_xticks(x)
ax.set_xticklabels([])

Actual outcome

# 3.3.0rc1
ValueError: The number of FixedLocator locations (5), usually from a call to set_ticks, does not match the number of ticklabels (0).

Expected outcome

Unset tick labels but not error out, or raise a deprecation warning that this won't be possible in a future release.

Matplotlib version

  • Operating system: macOS
  • Matplotlib version: 3.3.0rc1
  • Matplotlib backend (print(matplotlib.get_backend())): MacOSX
  • Python version: 3.8.3

Installed using pip

@jklymak
Copy link
Member

jklymak commented Jun 23, 2020

I guess that needs better documentation. OTOH I’m not sure or not if we should support what you are after here. As also pointed out in the stackoverflow thread you should use a NullFormatter to do this cleanly. Just passing an empty list to the fixed formatter seems like something that worked by accident rather than a conscious API decision

Ping @efiring.

@jklymak jklymak added this to the v3.3.0 milestone Jun 23, 2020
@efiring
Copy link
Member

efiring commented Jun 23, 2020

Special-casing the empty list, possibly with a Deprecation, seems like a reasonable option here. I can imagine that the empty list idiom might be common; it's logical, and easy to use.

@jklymak jklymak added API: changes Release critical For bugs that make the library unusable (segfaults, incorrect plots, etc) and major regressions. labels Jun 23, 2020
@timhoffm
Copy link
Member

We have 5 usages of ax.set_xticklabels([]) in our docs. So it's at least implicitly supported and very likely to be used in the wild.

It's also used via plt.xticks([]). The xticks docs explicitly recommend this for deactivating ticks.

IMHO we should continue to support the empty list.

@burcakotlu
Copy link

May I ask how this problem is resolved in matplotlib 3.3.2?

"The number of FixedLocator locations"
ValueError: The number of FixedLocator locations (0), usually from a call to set_ticks, does not match the number of ticklabels (1).

Thanks

@jklymak
Copy link
Member

jklymak commented Apr 26, 2021

If you are still having this issue in 3.4.x please open a new issue with a reproducible example... Thanks!

@timhoffm
Copy link
Member

On 3.3.2 you can try

ax.set_xticks(x)
ax.set_xticklabels([''] * len(x))

@burcakotlu
Copy link

I resolved this issue by adding 1 to the numpy.arange function.
After this statement, I did not receive error from the code below.

panel1.set_xticks(np.arange(0, len(xlabels)+1, 1))

If there is only 1 xlabel, xticks must be [0 1] not [0].

Therefore, code below does not give error, since it places the tick label at position 0.5

panel1.set_xticklabels([])
mticks = panel1.get_xticks()
panel1.set_xticks((mticks[:-1] + mticks[1:]) / 2, minor=True)
panel1.tick_params(axis='x', which='minor', length=0, labelsize=50)
panel1.set_xticklabels(xlabels,minor=True)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
API: changes Release critical For bugs that make the library unusable (segfaults, incorrect plots, etc) and major regressions.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants