将旋转的xticklabels与它们各自的xticks对齐

Fil*_*eia 122 matplotlib

检查下图的x轴.如何将标签向左移动一点,使它们与各自的刻度对齐?

我正在使用以下方式旋转标签:

ax.set_xticks(xlabels_positions)
ax.set_xticklabels(xlabels, rotation=45)
Run Code Online (Sandbox Code Playgroud)

但是,正如您所看到的,旋转以文本标签的中间为中心.这使它看起来像是向右移动了.

我试过用这个代替:

ax.set_xticklabels(xlabels, rotation=45, rotation_mode="anchor")
Run Code Online (Sandbox Code Playgroud)

......但它没有按照我的意愿行事.并且"anchor"似乎是rotation_mode参数允许的唯一值.

例

Rut*_*ies 184

您可以设置ticklabels的水平对齐方式,请参阅下面的示例.如果你想象一个围绕旋转标签的矩形框,你想要与刻度点对齐矩形的哪一边?

根据您的描述,您需要:ha ='right'

n=5

x = np.arange(n)
y = np.sin(np.linspace(-3,3,n))
xlabels = ['Ticklabel %i' % i for i in range(n)]

fig, axs = plt.subplots(1,3, figsize=(12,3))

ha = ['right', 'center', 'left']

for n, ax in enumerate(axs):
    ax.plot(x,y, 'o-')
    ax.set_title(ha[n])
    ax.set_xticks(x)
    ax.set_xticklabels(xlabels, rotation=40, ha=ha[n])
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

  • 如果您只想使用现有标签,也可以使用`xlabels = ax.get_xticklabels()`. (12认同)

Bor*_*lik 10

旋转标签肯定是可能的.请注意,这样做会降低文本的可读性.另一种方法是使用如下代码替换标签位置:

import numpy as np
n=5

x = np.arange(n)
y = np.sin(np.linspace(-3,3,n))
xlabels = ['Long ticklabel %i' % i for i in range(n)]


fig, ax = plt.subplots()
ax.plot(x,y, 'o-')
ax.set_xticks(x)
labels = ax.set_xticklabels(xlabels)
for i, label in enumerate(labels):
    label.set_y(label.get_position()[1] - (i % 2) * 0.075)
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

有关更多背景和替代方案,请参阅我的博客上的这篇文章


pyp*_*ypy 7

如果你不想修改 xtick 标签,你可以使用:

plt.xticks(rotation=45)

  • 但它也有同样的问题,即标签对齐错误。但是,要使用 @RutgierCassies 的技巧,确实可以使用 `plt.xticks(rotation=45,ha='right')` (6认同)

tdy*_*tdy 7

接受ha='right'的仍然不足以在视觉上将标签与刻度对齐

  • 如果rotation=45,然后添加rotation_mode='anchor'
  • 否则添加一个 ScaledTranslation

rotation_mode='anchor'

如果旋转角度大约为 45 度,则设置rotation_mode='anchor'最简单:

45 度时默认/锚点旋转模式的比较

x = xticks = np.arange(10)
xticklabels = (f'xticklabel {tick}' for tick in xticks)

fig, ax = plt.subplots()
ax.bar(x, x - 4.5)
ax.set_xticks(xticks)

# since rotation=45, anchor the rotation to fix label/tick alignment
ax.set_xticklabels(xticklabels, rotation=45, ha='right', rotation_mode='anchor')
Run Code Online (Sandbox Code Playgroud)

然而,这对于 70 度(见左图)等其他角度效果不佳,在这种情况下,我们需要应用 a ScaledTranslation(见右图):

70 度旋转模式和 ScaledTranslation 的比较


ScaledTranslation

如果旋转角度更极端,或者您只是想要更细粒度的控制,则ScaledTranslation按照如何在 matplotlib 中移动刻度标签中的描述应用 a :

有和没有 ScaledTranslation 的比较

...
ax.set_xticklabels(xticklabels, rotation=70, ha='right')

# create offset transform (x=5pt)
from matplotlib.transforms import ScaledTranslation
dx, dy = 5, 0
offset = ScaledTranslation(dx/fig.dpi, dy/fig.dpi, scale_trans=fig.dpi_scale_trans)

# apply offset transform to all xticklabels
for label in ax.xaxis.get_majorticklabels():
    label.set_transform(label.get_transform() + offset)
Run Code Online (Sandbox Code Playgroud)


Jef*_*own 6

一种简单,无循环的替代方法是将horizontalalignmentText属性用作xticks[1] 的关键字参数。在下面的注释行中,我强制xticks对齐方式为“正确”。

n=5
x = np.arange(n)
y = np.sin(np.linspace(-3,3,n))
xlabels = ['Long ticklabel %i' % i for i in range(n)]
fig, ax = plt.subplots()
ax.plot(x,y, 'o-')

plt.xticks(
        [0,1,2,3,4],
        ["this label extends way past the figure's left boundary",
        "bad motorfinger", "green", "in the age of octopus diplomacy", "x"], 
        rotation=45,
        horizontalalignment="right")    # here
plt.show()
Run Code Online (Sandbox Code Playgroud)

yticks默认情况下,其右边缘已与刻度线对齐,但xticks默认情况下显示为“中心”。)

[1] 如果您搜索短语“文本属性” ,则会xticks文档中找到描述的内容


Fra*_*ois 5

我显然迟到了,但有一个官方示例使用

plt.setp(ax.get_xticklabels(), rotation=45, ha="right", rotation_mode="anchor")
Run Code Online (Sandbox Code Playgroud)

旋转标签,同时保持它们与刻度正确对齐,这既干净又容易。

请参阅:https : //matplotlib.org/stable/gallery/images_contours_and_fields/image_annotated_heatmap.html