在python matplotlib中旋转轴文本


313

我不知道如何在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')

3
这个答案对于重要的东西关于与对准旋转标签ha(水平对齐)
LondonRob

Answers:


510

这对我有用:

plt.xticks(rotation=90)

8
万一其他人正在使用mpld3,并且对这些解决方案都无法使用而感到沮丧。mpld3 支持旋转。
beetree

4
使这些停留在图形/窗口中的额外点。我的一半在外面。
Gauthier

1
绘图称此。即,ax.plot(...)然后是第一次plt.xticks(rotation=90)
CGFoX

161

简单的方法

如此处所述matplotlib.pyplot figure该类中存在一个现有方法,该方法可以自动轮换日期以适合您的身材。

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

fig.autofmt_xdate()

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

非日期时间对象

根据languitar的评论,我建议的非datetime方法xticks在缩放等情况下无法正确更新。如果它不是datetime用作x轴数据的对象,则应遵循Tommy的回答

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

3
这是最好的方法,因为它简洁明了,可以对现有的自动生成的刻度进行操作,并且可以调整绘图边距,以便于阅读。其他方法使刻度线离开页面,需要进一步的操作(例如plt.tight_layouts())来进行调整。
EL_DON

如果您使用了定位器和格式化程序,则“其他”方法在以后应用时可能会破坏其效果。
languitar '17

73

这里有许多“正确”的答案,但由于我认为一些细节中遗漏了一些,因此我将再添加一个。OP要求旋转90度,但我将更改为45度,因为当您使用非零或90度的角度时,还应该更改水平对齐方式;否则,您的标签将偏离中心并产生误导性(我猜很多来这里的人都想将轴旋转到90以外的位置)。

最简单/最少的代码

选项1

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

如前所述,如果您宁愿采用面向对象的方法,那可能也不是所希望的。

选项2

另一种快速方法(该方法适用于日期对象,但似乎可以在任何标签上使用;不过建议不要这样做):

fig.autofmt_xdate(rotation=45)

fig 您通常可以从:

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

面向对象/直接与 ax

选项3a

如果您有标签列表:

labels = ['One', 'Two', 'Three']
ax.set_xticklabels(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_xticklabels(ax.get_xticklabels(), rotation=45, ha='right')

选项4

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

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

选项5

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

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

选项6

此选项很简单,但是AFAIK不能以这种方式设置标签水平对齐,因此,如果角度不为90,则另一个选项可能会更好。

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

编辑: 关于此确切的“错误”的讨论,并且可能会针对v3.2.0以下问题进行修复:https : //github.com/matplotlib/matplotlib/issues/13774


65

尝试pyplot.setp。我认为您可以执行以下操作:

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

2
Traceback (most recent call last): File "plotter.py", line 23, in <module> plt.setp(time, rotation=90) File "/usr/lib64/python2.7/site-packages/matplotlib/pyplot.py", line 183, in setp ret = _setp(*args, **kwargs) File "/usr/lib64/python2.7/site-packages/matplotlib/artist.py", line 1199, in setp func = getattr(o, funcName) AttributeError: 'datetime.datetime' object has no attribute 'set_rotation'
tMC 2012年

我想我错过了一步。编辑后的示例有帮助吗?我离matplotlib专家还很远,可能会有更好的方法。
opiethehokie 2012年

1
这似乎根本不起作用-图像(在我的机器上)完全混乱了。输出图像上遍布黑线...几乎看起来像条形码。这很奇怪。
tMC 2012年

这是哪个版本的matplotlib?在1.2.0中,setp(subplot(111).get_xticklabels(), rotation=90)可以与Qt4Agg后端正常工作。就我而言,它是由重置的plt.hist(),所以我在之后调用它,尽管plt.plot()没有重置它,所以您应该没问题。
drevicko

1
@tMC在mpl 1.2.0中,我复制了您的代码(带有一些虚拟数据),并locs, labels = plt.xticks() plt.setp(labels, rotation=90)在之前添加了plt.plot(time, delay)它,并且效果很好。
drevicko

54

来自的Appart

plt.xticks(rotation=90)

这也是可能的:

plt.xticks(rotation='vertical')

它可行,但是情节的高度存在一些问题
Roberto Marzocchi

plt.xticks(rotation=45) plt.savefig(nomefile,dpi=150, optimize=True) plt.clf()
Roberto Marzocchi

49

我想出了一个类似的例子。同样,rotation关键字是..嗯,这是关键。

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 ) ;

看起来好像datetime
可行

32

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

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

2
这似乎不再起作用。没有任何影响。
zbyszek

31

如果使用plt

plt.xticks(rotation=90)

如果使用熊猫或海生动物进行绘图,则以绘图的ax轴为例:

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

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

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

所有这些方法已在其他答案中显示。这个答案在这里添加了什么?
ImportanceOfBeingErnest

@ImportanceOfBeingErnest旨在帮助那些使用熊猫或海洋生物(而不是直接使用matplotlib)进行绘图的人。
Manavalan Gajapathy

for tick in ax.get_xticklabels(): tick.set_rotation(45)为我做了把戏。
美联社

30

如果要对轴对象施加旋转,最简单的方法是使用tick_params。例如。

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

Matplotlib文档参考在这里

当您有由返回的轴数组时,此功能很有用plt.subplots,并且比使用更方便,set_xticks因为在这种情况下,您还需要设置刻度标签,并且还需要遍历刻度线(因为明显的原因)


1
除此之外,该解决方案还适用于pandas数据框的plot函数,因为它也返回轴对象。在这里检查。非常方便的功能。pd_dataframe.plot().tick_params(axis='x', labelrotation=90)
metinsenturk '19

唯一的问题是,如果使用类似,我不知道如何正确地水平对齐标签labelrotation=30
getup8


3

这将取决于您要绘制的内容。

import matplotlib.pyplot as plt

 x=['long_text_for_a_label_a',
    'long_text_for_a_label_b',
    'long_text_for_a_label_c']
y=[1,2,3]
myplot = plt.plot(x,y)
for item in myplot.axes.get_xticklabels():
    item.set_rotation(90)

对于给您一个轴对象的大熊猫和海豚:

df = pd.DataFrame(x,y)
#pandas
myplot = df.plot.bar()
#seaborn 
myplotsns =sns.barplot(y='0',  x=df.index, data=df)
# you can get xticklabels without .axes cause the object are already a 
# isntance of it
for item in myplot.get_xticklabels():
    item.set_rotation(90)

如果您需要旋转标签,则可能还需要更改字体大小,可以使用font_scale=1.0该方法。


2

要将x轴标签旋转到90度

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

我喜欢您的答案有多短,但是您发布的内容无效的Python代码。我不清楚如何将其解释为有效的python代码。
Dave C

1

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

plt.xticks(rotation=XX)

但是也

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

例如,对于日期,我使用了rotation = 45和bottom = 0.20,但是您可以对数据进行一些测试

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.