旋转坐标轴刻度标签

573
我无法弄清楚如何在X轴上旋转文本。这是一个时间戳,随着样本数量的增加,它们越来越接近,直到重叠。我想将文本旋转90度,这样样本越靠近,它们就不会重叠。
以下是我的代码,除了我无法弄清楚如何旋转X轴文本之外,它运行得很好。
import sys

import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
import datetime

font = {'family' : 'normal',
        'weight' : 'bold',
        'size'   : 8}

matplotlib.rc('font', **font)

values = open('stats.csv', 'r').readlines()

time = [datetime.datetime.fromtimestamp(float(i.split(',')[0].strip())) for i in values[1:]]
delay = [float(i.split(',')[1].strip()) for i in values[1:]]

plt.plot(time, delay)
plt.grid(b='on')

plt.savefig('test.png')
13个回答

901

这对我有用:

plt.xticks(rotation=90)

400

这里有很多“正确”的答案,但我想再添加一个,因为我认为一些细节被省略了。虽然OP要求90度旋转,但我将其改为45度,因为当您使用非零或90度的角度时,您应该同时更改水平对齐方式;否则,您的标签将偏离中心,有点误导(我猜很多人来到这里都想将轴旋转到其他角度而不是90)。

最简单/代码最少

选项1

plt.xticks(rotation=45, ha='right')

如前所述,如果您更喜欢采用面向对象的方法,则可能不希望这样做。

选项2

另一种快速的方法(它旨在处理日期对象,但似乎适用于任何标签;虽然不建议这样做):

fig.autofmt_xdate(rotation=45)

fig通常可以通过以下方式获取:

  • fig = plt.gcf()
  • fig = plt.figure()
  • fig, ax = plt.subplots()
  • fig = ax.figure

面向对象 / 直接处理ax

选项3a

如果您有标签列表:

labels = ['One', 'Two', 'Three']
ax.set_xticks([1, 2, 3])
ax.set_xticklabels(labels, rotation=45, ha='right')

在Matplotlib的后续版本(3.5+)中,您只需使用set_xticks即可:

ax.set_xticks([1, 2, 3], labels, rotation=45, ha='right')

选项3b

如果您想从当前图获取标签列表:

# Unfortunately you need to draw your figure first to assign the labels,
# otherwise get_xticklabels() will return empty strings.
plt.draw()
ax.set_xticks(ax.get_xticks())
ax.set_xticklabels(ax.get_xticklabels(), rotation=45, ha='right')

如上所述,在较新的Matplotlib版本(3.5+)中,你只需使用set_xticks即可:

ax.set_xticks(ax.get_xticks(), ax.get_xticklabels(), rotation=45, ha='right')

选项4

与上述类似,但手动循环。

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

选项 5

在这里我们仍然使用 pyplot(作为plt),但它是面向对象的,因为我们正在更改特定ax对象的属性。

plt.setp(ax.get_xticklabels(), rotation=45, ha='right')

选项六

这个选项很简单,但据我所知,你无法通过这种方式设置标签的水平对齐方式,如果你的角度不是90度,那么另一个选项可能更好。

ax.tick_params(axis='x', labelrotation=45)

编辑: 关于这个“bug”的讨论已经出现了,但尚未发布修复版本(截至3.4.0): https://github.com/matplotlib/matplotlib/issues/13774


选项5不是面向对象的,因为plt.setp将自动针对“当前”Axes进行操作,无论它是什么。你给它ax.get_xticklabels()作为参数,但根据你最后处理的Axes是ax2还是其他什么,它可以应用于不同的Axes上。当有多个Axes时,人们必须避免使用plt.的方法。 - Guimoute

211

简单方法

在此处描述所述,matplotlib.pyplot figure类中存在一种现有的方法,它可以自动为您的图形适当地旋转日期。

您可以在绘制数据后调用它(即:ax.plot(dates,ydata)):

fig.autofmt_xdate()

如果您需要进一步格式化标签,请查看上面的链接。

非日期时间对象

根据languitar的评论,我建议用于非日期时间xticks的方法在缩放等操作时无法正确更新。如果您的x轴数据不是datetime对象,则应遵循Tommy的答案

for tick in ax.get_xticklabels():
    tick.set_rotation(45)

71

尝试使用pyplot.setp。我认为你可以这样做:

x = range(len(time))
plt.xticks(x,  time)
locs, labels = plt.xticks()
plt.setp(labels, rotation=90)
plt.plot(x, delay)

58

除了...之外

plt.xticks(rotation=90)

这也是可能的:

plt.xticks(rotation='vertical')

53

我想到了一个类似的例子。同样地,旋转关键字是...嗯,它是关键。

from pylab import *
fig = figure()
ax = fig.add_subplot(111)
ax.bar( [0,1,2], [1,3,5] )
ax.set_xticks( [ 0.5, 1.5, 2.5 ] )
ax.set_xticklabels( ['tom','dick','harry'], rotation=45 ) ;

51

如果你想在轴对象上应用旋转,最简单的方法是使用 tick_params。例如:

ax.tick_params(axis='x', labelrotation=90)

Matplotlib文档参考在这里

当您有一个由plt.subplots返回的轴数组时,此功能非常有用,并且比使用set_xticks更方便,因为在那种情况下,您还需要设置刻度标签,而且比遍历刻度更方便(出于显而易见的原因)


40

如果使用 plt:

plt.xticks(rotation=90)

如果使用pandas或seaborn绘制图形,假设ax为绘图的坐标轴:

ax.set_xticklabels(ax.get_xticklabels(), rotation=90)

另一种完成上述操作的方法:

for tick in ax.get_xticklabels():
    tick.set_rotation(45)

37

我受cjohnson318答案的启发,但不想提供一个硬编码的标签列表;我想要旋转现有的标签:

for tick in ax.get_xticklabels():
    tick.set_rotation(45)

15

最简单的解决方案是使用:

plt.xticks(rotation=XX)

但也

# Tweak spacing to prevent clipping of tick-labels
plt.subplots_adjust(bottom=X.XX)

例如,对于日期,我使用了rotation=45和bottom=0.20,但您可以针对自己的数据进行测试。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接