如何在matplotlib中移动tick的标签?

sna*_*mer 32 python label matplotlib

我想沿着x轴水平移动一些刻度标签,而不移动相应的刻度.

更具体地说,当旋转标签时plt.setp,标签文本的中心保持与刻度线对齐.我想将这些标签向右移动,以便标签的近端对齐,如下图所示.

在此输入图像描述

我知道这篇文章这一个,但答案很有意思组装机,而不是严格的问题的答案.

我的代码:

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()
Run Code Online (Sandbox Code Playgroud)

奇怪的是,set_y表现得像预期的那样,但即使我设定x了幻想,标签也不会移动一个iota.(使用plot_date可能引入额外的混淆,但实际上也是如此plot.)

Imp*_*est 39

首先,让我们使用mcve来显示问题.

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()
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

现在正如其他已经指出的那样,您可以使用文本的水平对齐方式.

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

在此输入图像描述

您可以使用rotation_mode参数让旋转发生在文本的左上角,在这种情况下给出稍微好一点的结果.

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

在此输入图像描述

如果这些选项的细度不够精细,即你想要更准确地定位标签,例如将它移到某一点的侧面,你可以使用变换.以下将使用a将标签在水平方向上偏移5个点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)
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

与例如@explorerDude提供的解决方案相比,这样做的优点是偏移量与图中的数据无关,因此它通常适用于任何绘图,并且对于给定的字体大小看起来相同.

  • Matplotlib 图形使用每英寸 72 点 (ppi)。因此,要将某物移动 x 点,您可以将其移动 x/72 英寸。您可能还想阅读 [this answer](/sf/answers/3334768181/) 的 dpi/ppi。 (4认同)

Mat*_*DMo 21

代替

ax2.xaxis.get_majorticklabels()[2].set_y(-.1)
ax2.xaxis.get_majorticklabels()[2].set_x(10**99)
Run Code Online (Sandbox Code Playgroud)

使用set_horizontalalignment()轴上的每个刻度:

for tick in ax2.xaxis.get_majorticklabels():
    tick.set_horizontalalignment("left")
Run Code Online (Sandbox Code Playgroud)

导致:

  • 感谢您的回答.它没有提供太大的灵活性:"左","右","中心".我正在尝试分配精确的坐标.我花了很多时间尝试,我真正关心的是要知道它是否完全可能. (7认同)

小智 13

我找到了一种方法来将x轴的刻度标签移动任意且精确的数量,但这种方式危险地靠近陡峭而滑溜的悬崖,高耸在疯狂的海面之上.因此,只有非常勇敢或绝望的人才应该阅读......

话虽这么说,问题是标签的x位置是在渲染图形时设置的(我没有查看代码的那部分,但这是我的理解).所以你用set_x()做的一切都会在以后被覆盖.但是,有一种解决方法:您可以将补丁set_x用于某些刻度,以便不在绘制渲染器绘制它们的位置绘制标签:

import types
SHIFT = 10. # Data coordinates
for 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 )
Run Code Online (Sandbox Code Playgroud)

您可以选择性地仅对要移动的标签执行此操作,当然也可以为每个标签使用不同的移位.

如果有人知道如何在较低的疯狂程度上做到这一点,我会非常感兴趣...


sco*_*tle 6

另一种进行水平对齐的方法:

plt.xticks(ha='left')
Run Code Online (Sandbox Code Playgroud)