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

Fra*_*urt 19 python plot label matplotlib

如何在matplotlib中旋转xticklabels以使每个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')
Run Code Online (Sandbox Code Playgroud)

我获得:

在此输入图像描述

每个xticklabel之间的间距是不相等的.例如,"Full"和"token emb"之间的间距远大于"前馈"和"ANN"之间的间距.

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

Imp*_*est 44

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

在此输入图像描述

由于您总是希望将ticklabels链接到其标记,因此更改间距实际上不是一种选择.

但是,您可能希望对齐它们,因此右上角是它们在刻度线下方定位的参考.

使用horizontalalignmentha参数,并将其设置为"right":

ax.set_xticklabels(xticklabels, rotation = 45, ha="right")
Run Code Online (Sandbox Code Playgroud)

这导致以下情节:

在此输入图像描述

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

ax.set_xticklabels(xticklabels, rotation = 45, va="center", position=(0,-0.28))
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

  • @Wouter 哦,不,不要那样做!我已经更新了当你用自动滴答绘制一些东西时如何做的答案。 (2认同)

gbi*_*nux 6

这是一个很好的资源,提供了多种选择。它们并不完美,但基本上还可以:

https://www.pythoncharts.com/2019/05/17/rotating-axis-labels/

更新:

matplotlib.text.Text.set_rotation_mode我查看了(链接)的文档:

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

因此,如果rotation_mode未指定,则首先旋转文本,然后对齐文本。ha="right"在这种模式下,即使使用了边界框,也不完全是文本的右上角。

如果rotation_mode="anchor",则文本直接围绕锚点 ( ha="right") 旋转。

这是一个示例(改编自此处的代码)

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

现在绘图已正确对齐:

在此输入图像描述