4

How can one remove, say, the first and last tick label of a plot if the plot is logarithmic?

Classic example:

import matplotlib.pyplot as plt
import numpy as np

ax1 = plt.subplot(1, 3, 1)
x = np.logspace(-3,1,100)
plt.plot(x,np.random.random(size=100))
plt.xscale('log')
ax2 = plt.subplot(1, 3, 2, sharey = ax1)
plt.plot(x,np.random.random(size=100))
plt.tick_params(axis='y',labelleft='off')
plt.subplots_adjust(wspace=0)

Leads to overlapping labels on the x axis.

Now if I do the most straightforward thing via *_ticklabels, e.g.,

l = [""] + [i.get_text() for i in ax2.get_xticklabels()[1:-1]] + [""]
ax2.set_xticklabels(l)

it does not work (within a script that is, not if matplotlib draws the plot first).

One way I found around this is to use a custom ticker object. For example

from matplotlib.ticker import ScalarFormatter
class _MyTickFormatter(ScalarFormatter):
    def __init__(self, hide):
        self.hide = hide
        super(self.__class__, self).__init__()        

    def __call__(self, x, pos=None):
        N = len(self.locs)
        hide = [ N + i if i < 0 else i for i in self.hide ]

        if pos in hide:
            return ''
        else:
            return self.pprint_val(x)

With this one can simply do ax2.set_major_formatter(_MyTickFormatter([0,-1])).

However, if the x-axis is, e.g., logarithmic (as above). Then the solution needs yet another custom tickformatter...

Another possibility is to use the MaxNLocator as described in this answer by Bernie. However, using this in a logarithmic axes leaves me with only one tick (as it should use the LogLocator, I assume).

Any ideas how I could solve this dilemma?

Community
  • 1
  • 1
user1834164
  • 377
  • 3
  • 13

3 Answers3

3

Try the following approach:

    xticks = ax.xaxis.get_major_ticks()
    xticks[0].label1.set_visible(False)
    xticks[-1].label1.set_visible(False)

It should remove first and last.

armatita
  • 12,825
  • 8
  • 48
  • 49
  • 1
    This does not seem to work within a script & with logarithmic axis but only if matplotlib drew the figure first. See my paragraph about `set_xticklabels` above. I will update my question to make it clearer. – user1834164 Mar 17 '16 at 15:50
  • That is strange. I would not expect the thick behavior to change depending on type of scale. The only solution out the top of my head is that you don't put the "log" scale and select the tick positions yourself (ax.set_xticks(positions)) to mimic the same behavior. Would this solve your problem? – armatita Mar 17 '16 at 15:57
  • hm...no as I am looking for an automated way which can be used for a variety of plots. Maybe someone else has a better idea. I think it has to work with either the tickformatter or the ticklocator classes. – user1834164 Mar 17 '16 at 16:09
  • 1
    OK I found the problem. In 'log' axis the first & last tick are by default labeled empty it seems? – user1834164 Mar 20 '16 at 19:36
2

As user1834164 has commented,"In 'log' axis the first & last tick are by default labeled empty it seems".

x = np.linspace(0,10,100)
y = np.exp(x)
plot(x,y)
yscale('log')
gca().yaxis.get_major_ticks()[-2].label1.set_visible(False)
gca().yaxis.get_major_ticks()[1].label1.set_visible(False)

So simply change indexes from 0 to 1 and from -1 to -2, and armatita's answer works.

Figure, produced by the code above

Community
  • 1
  • 1
queezz
  • 1,832
  • 2
  • 20
  • 26
0

This wont solve your question, but hopefully it helps you anyway. You could try to rotate the ticks labels. I found this very useful when dealing with long overlapping x-labels. Either you give rotate=45 as a kwarg when setting the x-ticks or you do it later with for example

for tick in ax.get_xticklabels():
    tick.set_rotation(45)
pathoren
  • 1,634
  • 2
  • 14
  • 22