Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to move a tick label in matplotlib

I would like to move some ticks' labels horizontally along the x-axis, without moving the corresponding ticks.

More specifically, when rotating labels with plt.setp, the centers of the labels' text stay aligned with the ticks. I would like to shift those labels to the right, so that the near ends of the labels get aligned instead as suggested on the image below.

enter image description here

I am aware of this post and this one, however the answers are interesting kludges rather than strict answers to the question.

my code:

import matplotlib.pyplot as plt import numpy as np import datetime  # my fake data dates = np.array([datetime.datetime(2000,1,1) + datetime.timedelta(days=i) for i in range(365*5)]) data = np.sin(np.arange(365*5)/365.0*2*np.pi - 0.25*np.pi) + np.random.rand(365*5) /3  # creates fig with 2 subplots fig = plt.figure(figsize=(10.0, 6.0)) ax = plt.subplot2grid((2,1), (0, 0)) ax2 = plt.subplot2grid((2,1), (1, 0)) ## plot dates ax2.plot_date( dates, data )  # rotates labels  plt.setp( ax2.xaxis.get_majorticklabels(), rotation=-45 )   # try to shift labels to the right ax2.xaxis.get_majorticklabels()[2].set_y(-.1) ax2.xaxis.get_majorticklabels()[2].set_x(10**99)  plt.show() 

Strangely enough, set_y behaves as expected, but even if I set x to a fantasillion, the labels would not move by one iota. (The use of plot_date may introduce additional confusion, but the same actually happens with plot.)

like image 810
snake_charmer Avatar asked Feb 19 '15 20:02

snake_charmer


People also ask

How do I change the position of a label in Matplotlib?

With matplotlib version 3.3. 0, the matplotlib functions set_xlabel and set_ylabel have a new parameter “loc” that can help adjust the positions of axis labels. For the x-axis label, it supports the values 'left', 'center', or 'right' to place the label towards left/center/right.

How do I move the Xticks in Python?

If you know the tick positions, you can do something like for pos, tick in zip(ticks, ax. xaxis. get_majorticklabels()): tick. set_x(pos - 0.1) tick.

How do I center a tick label in Matplotlib?

However there is no direct way to center the labels between ticks. To fake this behavior, one can place a label on the minor ticks in between the major ticks, and hide the major tick labels and minor ticks.


1 Answers

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

import numpy as np import datetime import matplotlib.pyplot as plt plt.rcParams["date.autoformatter.month"] = "%b %Y"  # my fake data dates = 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 subplots fig, ax = plt.subplots(figsize=(6,2)) ## plot dates ax.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.transforms  plt.setp( ax.xaxis.get_majorticklabels(), rotation=-45)   # Create offset transform by 5 points in x direction dx = 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.

like image 86
ImportanceOfBeingErnest Avatar answered Sep 29 '22 00:09

ImportanceOfBeingErnest