如何在 matplotlib 中移动刻度标签
问题描述
我想沿 x 轴水平移动一些刻度的标签,而不移动相应的刻度.
更具体地说,当使用 plt.setp
旋转标签时,标签文本的中心与刻度线保持对齐.我想将这些标签向右移动,以便标签的近端对齐,而不是如下图所示.
我知道
现在正如其他答案已经指出的那样,您可以使用文本的水平对齐方式.
# 旋转标签并将它们水平向左对齐plt.setp(ax.xaxis.get_majorticklabels(),rotation=-45, ha="left")
您可以使用 rotation_mode
参数让旋转发生在文本的左上角,在这种情况下会产生更好的结果.
# 旋转标签并将它们水平向左对齐plt.setp(ax.xaxis.get_majorticklabels(), rotation=-45, ha="left", rotation_mode="anchor")
如果这些选项不够精细,即您希望更准确地定位标签,例如将它移到一边,您可以使用变换.以下将使用 matplotlib.transforms.ScaledTranslation
将标签在水平方向上偏移 5 个点.
导入 matplotlib.transformsplt.setp(ax.xaxis.get_majorticklabels(),旋转=-45)# 在 x 方向创建 5 个点的偏移变换dx = 5/72.dy = 0/72.偏移量 = matplotlib.transforms.ScaledTranslation(dx, dy, fig.dpi_scale_trans)# 对所有 x 刻度标签应用偏移变换.对于 ax.xaxis.get_majorticklabels() 中的标签:label.set_transform(label.get_transform() + offset)
与例如相比,这样做的优势@explorerDude 提供的解决方案是偏移量独立于图表中的数据,因此它通常适用于任何绘图并且对于给定的字体大小看起来相同.
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.
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
.)
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()
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" )
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")
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)
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.
相关文章