How to move an tick label in matplotlib How to move an tick label in matplotlib python python

How to move an tick label in matplotlib


First of all, let's use a mcve to show the problem.

import numpy as npimport datetimeimport matplotlib.pyplot as pltplt.rcParams["date.autoformatter.month"] = "%b %Y"# my fake datadates = np.array([datetime.datetime(2000,1,1) + datetime.timedelta(days=i) for i in range(365)])data = np.sin(np.arange(365)/365.0*2*np.pi - 0.25*np.pi) + np.random.rand(365) /3# creates fig with 2 subplotsfig, ax = plt.subplots(figsize=(6,2))## plot datesax.plot_date( dates, data )# rotates labels plt.setp( ax.xaxis.get_majorticklabels(), rotation=-45 ) plt.tight_layout()plt.show()

enter image description here

Now as other anwers pointed out already, you may use horizontal alignment of the text.

# rotates labels and aligns them horizontally to left plt.setp( ax.xaxis.get_majorticklabels(), rotation=-45, ha="left" )

enter image description here

You may use the rotation_mode argument to let the rotation happen about the top left point of the text, giving a slightly nicer result in this case.

# rotates labels and aligns them horizontally to left plt.setp( ax.xaxis.get_majorticklabels(), rotation=-45, ha="left", rotation_mode="anchor") 

enter image description here

In case those options are not fine grained enough, i.e. you want to position the labels more accurately, e.g. shifting it to the side by some points, you may use a transform. The following would offset the label by 5 points in horizontal direction, using a matplotlib.transforms.ScaledTranslation.

import matplotlib.transformsplt.setp( ax.xaxis.get_majorticklabels(), rotation=-45) # Create offset transform by 5 points in x directiondx = 5/72.; dy = 0/72. offset = matplotlib.transforms.ScaledTranslation(dx, dy, fig.dpi_scale_trans)# apply offset transform to all x ticklabels.for label in ax.xaxis.get_majorticklabels():    label.set_transform(label.get_transform() + offset)

enter image description here

The advantage of this, compared to e.g. the solution provided by @explorerDude is that the offset is independent on the data in the graph, such that it is generally applicable to any plot and would look the same for a given fontsize.


Instead of

ax2.xaxis.get_majorticklabels()[2].set_y(-.1)ax2.xaxis.get_majorticklabels()[2].set_x(10**99)

use the set_horizontalalignment() for each tick on the axis:

for tick in ax2.xaxis.get_majorticklabels():    tick.set_horizontalalignment("left")

resulting in:


I found a way to shift the tick labels of the x-axis by an arbitrary and exact amount, but this way runs dangerously close to the steep and slippery cliffs towering above the sea of madness. So only the very brave or desperate should read on...

That being said, the problem is that the x position of the labels are set when the drawing is rendered (I have not looked into that part of the code, but that is my understanding). So everything you do with set_x() is overridden later. However, there is a way around that: you can monkey patch set_x for certain ticks so that the labels are not drawn where the renderer wants to draw them:

import typesSHIFT = 10. # Data coordinatesfor label in ax2.xaxis.get_majorticklabels():    label.customShiftValue = SHIFT    label.set_x = types.MethodType( lambda self, x: matplotlib.text.Text.set_x(self, x-self.customShiftValue ),                                     label, matplotlib.text.Text )

You can do this selectively only for the labels you want to shift and you can of course also use a different shift for every label.

If anybody knows how to do this on a lower madness level, I would be very interested...