How to Move a Tick Label in Matplotlib

How to move a tick label in matplotlib

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()

Sample Image

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" )

Sample Image

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")

Sample Image

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)

Sample Image

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.

Move x-axis tick labels one position to left

Your labels are correctly positioned, as shown by the fact that if you were to rotate them 90°, they would be perfectly aligned with your bars.

fig1, ax = plt.subplots()

palette = ['#2a5495', '#07a64c', '#e979ad', '#d88432', '#2a5495',
'#b7040e', '#82c5db', '#b9c09b', '#cd065d', '#4b117f']

labels = ['Long misaligned label {}'.format(i) for i in range(10)]
x = range(10)
y = 100+100*np.random.random((10,))

width = 1.0
lefts = [x * width for x, _ in enumerate(y)]
ax.bar(left = lefts, height = y, width = width, tick_label = labels, color = palette)

ax.axis(ymin = 0, ymax = 200, xmin = -0.5, xmax = 9.5)
ax.tick_params(axis='x', which='major', labelsize=8)
ax.set_xticklabels(ax.xaxis.get_majorticklabels(), rotation=90)

fig1.tight_layout()
plt.show()

Sample Image

The problem is that the labels are centered horizontally, so when you rotate them 45°, they appear to be aligned with the wrong bar. To fix this, align the labels to the right, and they'll get back to their correct (visual) position.

plt.setp(ax.xaxis.get_majorticklabels(), ha='right')

Sample Image

Another (maybe simpler) option is to use the helper function Figure.autofmt_xdate(), which handles all of this for you.

Matplotlib move tick labels inside plot area

I guess you are completely on the right track. The problem is just to find the good parameters for the padding in order to have the ticklabels inside the axes. The padding is measured in points, so it makes sense to use much larger numbers than 0.5. Also the padding is different for x and y axis due to the text's alignment.

import matplotlib.pyplot as plt

fig, ax = plt.subplots()
ax.tick_params(axis="y",direction="in", pad=-22)
ax.tick_params(axis="x",direction="in", pad=-15)

plt.show()

Sample Image

How to move tick labels off left spine

Changing the transformation of the y-ticklabels back to the original y-axis transform would give you the desired ticks on the left side of the axes.

plt.setp(ax.get_yticklabels(), transform=ax.get_yaxis_transform())

Sample Image

Complete code for reproducibility

import matplotlib.pyplot as plt

X = range(-10,5)
y = [i**2 for i in X]

fig, ax = plt.subplots(1,1, figsize=(10,8))
plt.plot(X, y)
ax.spines['top'].set_visible(False)
ax.spines['right'].set_visible(False)
ax.spines['left'].set_position('zero')

plt.setp(ax.get_yticklabels(), transform=ax.get_yaxis_transform())

plt.show()

How can I move a tick label only(without moving corresponding tick)?

From your comment "..mark out several important values on the x-axis" I think you shouldn't be changing the xticks and labels, but rather add vertical lines with appropriate annotation.

This means the grid over which your data remains regular and allows you to colourise important points, you could also add the numeric values as well fairly easily.

Example

import pylab as py

# Plot a sinc function
delta=2.0
x=py.linspace(-10,10,100)
y=py.sinc(x-delta)

# Mark delta
py.axvline(delta,ls="--",color="r")
py.annotate(r"$\delta$",xy=(delta+0.2,-0.2),color="r",size=15)
py.plot(x,y)

Simple sinc and annotation

Matplotlib: Move ticklabels between ticks

As you've noticed, they're centered by default and you're overriding the default behavior by specifying extent=[0, width, height, 0].

There are a number of ways to handle this. One is to use pcolor and set the edgecolors and linestyles to look like the gridlines (you actually need pcolor and not pcolormesh for this to work). However, you'll have to change the extents to get the ticks in the center as imshow does by default.

import matplotlib.pyplot as plt
import numpy as np

data = np.random.random((10,10))
labels = 'abcdefghij'

fig, ax = plt.subplots()
im = ax.pcolor(data, cmap='gray', edgecolor='black', linestyle=':', lw=1)
fig.colorbar(im)

# Shift ticks to be at 0.5, 1.5, etc
for axis in [ax.xaxis, ax.yaxis]:
axis.set(ticks=np.arange(0.5, len(labels)), ticklabels=labels)

plt.show()

Sample Image

Alternatively, you could turn on the minor grid and place it at the pixel boundaries. Because you want fixed labels, we'll just set everything manually. Otherwise, a MultipleLocator would make more sense:

import matplotlib.pyplot as plt
import numpy as np

data = np.random.random((10,10))
labels = 'abcdefghij'

fig, ax = plt.subplots()
im = ax.imshow(data, cmap='gray', interpolation='none')
fig.colorbar(im)

# Set the major ticks at the centers and minor tick at the edges
locs = np.arange(len(labels))
for axis in [ax.xaxis, ax.yaxis]:
axis.set_ticks(locs + 0.5, minor=True)
axis.set(ticks=locs, ticklabels=labels)

# Turn on the grid for the minor ticks
ax.grid(True, which='minor')

plt.show()

Sample Image

Matplotlib - Move X-Axis label downwards, but not X-Axis Ticks

use labelpad parameter:

pl.xlabel("...", labelpad=20)

or set it after:

ax.xaxis.labelpad = 20

Moving x-axis to the top of a plot in matplotlib

Use

ax.xaxis.tick_top()

to place the tick marks at the top of the image. The command

ax.set_xlabel('X LABEL')    
ax.xaxis.set_label_position('top')

affects the label, not the tick marks.

import matplotlib.pyplot as plt
import numpy as np
column_labels = list('ABCD')
row_labels = list('WXYZ')
data = np.random.rand(4, 4)
fig, ax = plt.subplots()
heatmap = ax.pcolor(data, cmap=plt.cm.Blues)

# put the major ticks at the middle of each cell
ax.set_xticks(np.arange(data.shape[1]) + 0.5, minor=False)
ax.set_yticks(np.arange(data.shape[0]) + 0.5, minor=False)

# want a more natural, table-like display
ax.invert_yaxis()
ax.xaxis.tick_top()

ax.set_xticklabels(column_labels, minor=False)
ax.set_yticklabels(row_labels, minor=False)
plt.show()

Sample Image



Related Topics



Leave a reply



Submit