68

The labels on my horizontal colorbar are too close together and I don't want to reduce text size further:

cbar = plt.colorbar(shrink=0.8, orientation='horizontal', extend='both', pad=0.02)
cbar.ax.tick_params(labelsize=8)

horizontal colorbar with bad labels

I'd like to preserve all ticks, but remove every other label.

Most examples I've found pass a user-specified list of strings to cbar.set_ticklabels(). I'm looking for a general solution.

I played around with variations of

cbar.set_ticklabels(cbar.get_ticklabels()[::2])

and

cbar.ax.xaxis.set_major_locator(matplotlib.ticker.MaxNLocator(nbins=4))

but I haven't found the magic combination.

I know there must be a clean way to do this using a locator object.

fuesika
  • 3,280
  • 6
  • 26
  • 34
David Shean
  • 1,015
  • 1
  • 9
  • 11
  • Have you seen http://stackoverflow.com/questions/6485000/python-matplotlib-colorbar-setting-tick-formator-locator-changes-tick-labels?rq=1 ? The ticks on colorbar can be finicky (as there is a layer in there to make it easy to flip from a vertical to horizontal with out changing too much of your code (ideally just adding a kwarg)) – tacaswell Dec 02 '13 at 22:54
  • Yeah. That post was helpful, and I ran update_ticks() during my preliminary tests, but the final solution offered still involves user-defined lists for tick locs/labels. – David Shean Dec 02 '13 at 23:29
  • In case someone wanted to use `pyplot` directly instead of `axes` object: https://matplotlib.org/stable/api/_as_gen/matplotlib.pyplot.xticks.html – M. Doosti Lakhani May 27 '21 at 06:45

5 Answers5

93

For loop the ticklabels, and call set_visible():

for label in cbar.ax.xaxis.get_ticklabels()[::2]:
    label.set_visible(False)
HYRY
  • 94,853
  • 25
  • 187
  • 187
  • 9
    Just as an alternate way of doing the exact same thing: You can do `plt.setp(cbar.ax.get_xticklabels()[::2], visible=False)`. This is identical, of course, but it can be handy to at least know about `setp`. Then again, a for loop is clearer and instantly readable, while `setp` isn't clear unless you're familiar with matplotlib. – Joe Kington Dec 03 '13 at 02:27
  • 3
    If your colorbar is oriented vertically, you will need to use `cbar.ax.yaxis.get_ticklabels()` instead – aseagram Jul 27 '14 at 02:09
  • 3
    Also, you can of course use `get_xticklabels()[1::2]` to hide very other label. This will usually be necessary if the start of your axis does not coincide with a tick but you still want to keep the first (visible) tick visible. – inVader Jul 22 '15 at 13:58
  • Is there a way to alternate the label position so that they go top, bottom, top, bottom ... ? That could help preserve all labels without overlapping. – Jason May 11 '16 at 09:55
  • 1
    An alternative way is to alternate top and bottom labels, rather than removing every other one. To do that I've come up with a solution: https://stackoverflow.com/q/37161022/2005415 – Jason Sep 14 '17 at 08:39
  • I can't believe how long it took me to find an answer to this seemingly simple question. I love matplotlib/pyplot but its interface is so arcane. Anyway, Thanks! – Luc Gendrot Dec 04 '17 at 20:59
  • If you want to keep every third this solution doesn't work. – SomJura Jul 27 '21 at 22:51
27

One-liner for those who are into that!

n = 7  # Keeps every 7th label
[l.set_visible(False) for (i,l) in enumerate(ax.xaxis.get_ticklabels()) if i % n != 0]
malla
  • 1,618
  • 1
  • 17
  • 23
  • 2
    Fantastic! This is the better than higher rated answers as it is more flexible. More than every second label can be hidden. – SomJura Jul 27 '21 at 22:53
  • 1
    for those who wish to copy-paste this magnificent one-liner: make sure you've assigned a variable name "ax" to any plot command you have written in your script (e.g. use ax = plt.subplot(); ax.plot(), instead of plt.subplot(); plt.plot()) – Brandon Jan 20 '22 at 19:22
  • I tried other proposed solutions. This worked for me (Python 2.7) – Samsky Mar 05 '23 at 23:06
  • @Brandon You can also use plt.gca() to get the current axis after doing a plot. I.e. do some plt.plot, then do ax = plt.gca() afterwards. Same goes for the figure, we can use plt.gcf() – Joe Iddon Mar 27 '23 at 10:43
16

Just came across this thread, nice answers. I was looking for a way to hide every tick between the nth ticks. And found the enumerate function. So if anyone else is looking for something similar you can do it like this.

for index, label in enumerate(ax.xaxis.get_ticklabels()):
    if index % n != 0:
        label.set_visible(False)
fredrik
  • 6,483
  • 3
  • 35
  • 45
6

I use the following to show every 7th x label:

plt.scatter(x, y)
ax = plt.gca()
temp = ax.xaxis.get_ticklabels()
temp = list(set(temp) - set(temp[::7]))
for label in temp:
    label.set_visible(False)
plt.show()

It's pretty flexible, as you can do whatever you want instead of plt.scatter. Hope it helps.

KetZoomer
  • 2,701
  • 3
  • 15
  • 43
Ben
  • 81
  • 1
  • 3
0

For some (mostly beginners) who aren't familiar or comfortable with the object oriented approach for matplotlib, here is a way to hide every 2nd label without needing to use ax:

        plt.plot(Allx,y)
   
        labels = []
        for i in range(len(Allx)): 
            if i % 2 == 0: 
                labels.append(Allx[i])
            else: 
                labels.append("")

         plt.xticks(ticks=Allx,labels=labels)
        
Misha
  • 1
  • 1