Python 如何在matplotlib中旋转xticklabel,使每个xticklabel之间的间距相等?

Python 如何在matplotlib中旋转xticklabel,使每个xticklabel之间的间距相等?,python,matplotlib,plot,label,Python,Matplotlib,Plot,Label,如何在matplotlib中旋转xticklabel,使每个xticklabel之间的间距相等 例如,使用此代码: import matplotlib.pyplot as plt import numpy as np # Data + parameters fontsize = 20 t = np.arange(0.0, 6.0, 1) xticklabels = ['Full', 'token emb', 'char emb', 'char LSTM', 't

如何在matplotlib中旋转xticklabel,使每个xticklabel之间的间距相等

例如,使用此代码:

import matplotlib.pyplot as plt
import numpy as np

# Data + parameters
fontsize = 20
t = np.arange(0.0, 6.0, 1)
xticklabels = ['Full', 'token emb', 'char emb', 'char LSTM', 
               'token LSTM', 'feed forward','ANN']

# Plotting
fig = plt.figure(1)
ax = fig.add_subplot(111)
plt.plot(t, t)
plt.xticks(range(0, len(t) + 1))
ax.tick_params(axis='both', which='major', labelsize=fontsize)
ax.set_xticklabels(xticklabels, rotation = 45)
fig.savefig('test_rotation.png', dpi=300, format='png', bbox_inches='tight')
我获得:

每个xticklabel之间的间距不相等。例如,“Full”和“token emb”之间的间隔远大于“feed forward”和“ANN”之间的间隔


我在Windows 7 SP1 x64 Ultimate上使用Matplotlib 2.0.0和Python 3.5 64位。

标签位于标记位置的中心。它们的边界框宽度不等,甚至可能重叠,这使它们看起来间隔不均

因为您总是希望标签链接到它们的记号,所以更改间距实际上不是一个选项

但是,您可能希望将它们对齐,以便右上角是它们在刻度下方定位的参考

使用
水平对齐
ha
参数,并将其设置为
“right”

这将导致以下绘图:

另一种方法是保持标签水平居中,但也可以垂直居中。这导致间距相等,但需要进一步调整其相对于轴的垂直位置

ax.set_xticklabels(xticklabels, rotation = 45, va="center", position=(0,-0.28))


如果像问题中那样手动指定刻度(例如通过
plt.xticks
或通过
ax.set\u xticks
),或者如果使用分类图,则可以使用上述选项。
如果标签自动显示,则不应使用设置标签。这通常会使标签和勾号位置变得不同步,因为
setxticklabels
将轴的格式设置为
FixedFormatter
,而定位器保持自动
自动定位器或任何其他自动定位器

在这些情况下,使用
plt.setp
设置现有标签的旋转和对齐

plt.setp(ax.get_xticklabels(), ha="right", rotation=45)
或在其上循环以设置各自的属性

for label in ax.get_xticklabels():
    label.set_ha("right")
    label.set_rotation(45)
例如

import numpy as np; np.random.seed(42)
import matplotlib.pyplot as plt

t = np.arange("2018-01-01", "2018-03-01", dtype="datetime64[D]")
x = np.cumsum(np.random.randn(len(t)))

fig, ax = plt.subplots()
ax.plot(t, x)

for label in ax.get_xticklabels():
    label.set_ha("right")
    label.set_rotation(45)

plt.tight_layout()
plt.show()

这里有一个很好的资源,提供了几个选项。它们并不完美,但基本上还可以:

更新:

我查阅了
matplotlib.text.text.set_rotation_mode
()的文档:

因此,如果未指定
rotation\u模式
,则首先旋转文本,然后对齐。在此模式下,即使使用了
ha=“right”
,边界框也不完全位于文本的右上角

如果
rotation\u mode=“anchor”
,文本将直接围绕锚点旋转(
ha=“right”

下面是一个示例(改编自)

导入matplotlib
将matplotlib.pyplot作为plt导入
将numpy作为np导入
标签=['G1_布拉_布拉','G2_布拉','G3_布拉','G4_布拉','G5_布拉']
男人的意思是[20,34,30,35,27]
女性的意思是[25,32,34,20,25]
x=np.arange(len(标签))#标签位置
宽度=0.35#钢筋宽度
图,ax=plt.子批次()
ax.bar(x-宽度/2,men_表示,宽度,标签='men')
ax.bar(x+width/2,women_表示宽度,标签='women')
#为标签、标题和自定义x轴标记标签等添加一些文本。
ax.set_ylabel(‘分数’)
ax.设置标题(“按组和性别划分的分数”)
ax.set_xticks(x)
ax.set\u xticklabels(
标签,
旋转=30,
ha=“对”,

旋转_mode=“anchor”)#它将标签置于记号的中心。我认为你不能改变这一点。@Wouter哦,不,不要那样做!我已经更新了当你用自动滴答作图时如何做的答案。再次感谢!!!你的解释很清楚。我已经更新了代码以使用循环并设置属性(我已经删除了以前的注释以避免引起混淆)。
import numpy as np; np.random.seed(42)
import matplotlib.pyplot as plt

t = np.arange("2018-01-01", "2018-03-01", dtype="datetime64[D]")
x = np.cumsum(np.random.randn(len(t)))

fig, ax = plt.subplots()
ax.plot(t, x)

for label in ax.get_xticklabels():
    label.set_ha("right")
    label.set_rotation(45)

plt.tight_layout()
plt.show()
set_rotation_mode(self, m)

Set text rotation mode.

Parameters: 
m : {None, 'default', 'anchor'}
If None or "default", the text will be first rotated, 
then aligned according to their horizontal and vertical 
alignments. 
If "anchor", then alignment occurs before rotation.
import matplotlib
import matplotlib.pyplot as plt
import numpy as np
labels = ['G1_bla_bla', 'G2_bla', 'G3_bla', 'G4_bla', 'G5_bla']
men_means = [20, 34, 30, 35, 27]
women_means = [25, 32, 34, 20, 25]
x = np.arange(len(labels))  # the label locations
width = 0.35  # the width of the bars
fig, ax = plt.subplots()
ax.bar(x - width/2, men_means, width, label='Men')
ax.bar(x + width/2, women_means, width, label='Women')
# Add some text for labels, title and custom x-axis tick labels, etc.
ax.set_ylabel('Scores')
ax.set_title('Scores by group and gender')
ax.set_xticks(x)
ax.set_xticklabels(
    labels, 
    rotation=30, 
    ha="right",  
    rotation_mode="anchor")  # <====== HERE is the key
ax.legend()
plt.show()