【问题标题】:Rotate axis text in python matplotlib在 python matplotlib 中旋转轴文本
【发布时间】:2012-06-15 10:49:35
【问题描述】:

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

【问题讨论】:

  • 有关将旋转标签与ha(水平对齐)对齐的重要信息,请参阅this answer

标签: python matplotlib


【解决方案1】:

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

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

【讨论】:

  • 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'
  • 我想我之前错过了一步。编辑后的示例有帮助吗?不过,我离 matplotlib 专家还很远,可能有更好的方法。
  • 这似乎根本不起作用-图像(在我的机器上)完全搞砸了。输出图像上到处都是黑线...几乎看起来像条码。这很奇怪。
  • 这是哪个版本的 matplotlib?对于 1.2.0,setp(subplot(111).get_xticklabels(), rotation=90) 可以与 Qt4Agg 后端一起正常工作。在我的情况下,它被plt.hist() 重置,所以我在之后调用它,虽然plt.plot() 没有重置它,所以你应该没问题。
  • @tMC 使用 mpl 1.2.0,我复制了您的代码(带有一些虚拟数据),在 plt.plot(time, delay) 之前添加了 locs, labels = plt.xticks() plt.setp(labels, rotation=90),它运行良好。
【解决方案2】:

我想出了一个类似的例子。再一次,轮换关键字是......嗯,它是关键。

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的时间戳
【解决方案3】:

简单的方法

作为described herematplotlib.pyplot figure 类中有一个现有方法可以自动为您的数字适当地旋转日期。

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

fig.autofmt_xdate()

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

非日期时间对象

根据 languitar 的评论,我为非日期时间 xticks 建议的方法在缩放等时不会正确更新。如果它不是用作您的 x- 的 datetime 对象轴数据,请关注Tommy's answer

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

【讨论】:

  • 这是最好的方法,因为它很简洁,它对现有的自动生成的刻度进行操作,它会调整绘图边距以使其可读。其他方法让刻度离开页面,需要进一步操作(例如 plt.tight_layouts())来调整它们。
  • 如果您使用了定位器和格式化程序,“其他”方法如果之后应用可能会破坏它们的效果。
【解决方案4】:

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

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

【讨论】:

  • 这似乎不再起作用了。没有任何影响。
【解决方案5】:

这对我有用:

plt.xticks(rotation=90)

【讨论】:

  • 如果其他人正在使用 mpld3,并且对这些解决方案都不起作用感到沮丧。 mpld3支持旋转。
  • 使这些留在图形/窗口内的额外积分。我的一半在外面。
  • 在绘图之后调用它。即,首先ax.plot(...) 然后plt.xticks(rotation=90)
  • 添加 plt.tight_layout() 让它们留在图中
  • 刚刚想通了。使用plt.sca(ax) 激活轴,并使用此答案。
【解决方案6】:
import pylab as pl
pl.xticks(rotation = 90)

【讨论】:

    【解决方案7】:

    plt.xticks(rotation=90)
    

    这也是可能的:

    plt.xticks(rotation='vertical')
    

    【讨论】:

    • 可以,但是剧情的高度有些问题
    • plt.xticks(rotation=45) plt.savefig(nomefile,dpi=150, optimize=True) plt.clf()
    【解决方案8】:

    如果使用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)
    

    【讨论】:

    • 所有这些方法已在其他答案中显示。这个答案在这里添加了什么?
    • @ImportanceOfBeingErnest 旨在帮助那些使用 pandas 或 seaborn 而不是直接使用 matplotlib 进行绘图的人。
    • for tick in ax.get_xticklabels(): tick.set_rotation(45) 帮了我大忙。
    • 谢谢,在遇到这个答案之前,我一直在使用 plt.xticks(rotation=45) 无济于事
    【解决方案9】:

    这取决于你在绘制什么。

    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)
    

    对于为您提供 Axes 对象的 pandas 和 seaborn:

    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 来做到这一点。

    【讨论】:

      【解决方案10】:

      如果您想在坐标区对象上应用旋转,最简单的方法是使用tick_params。例如。

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

      Matplotlib 文档参考here.

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

      【讨论】:

      • 除此之外,此解决方案也适用于 pandas 数据框的 plot 函数,因为它也返回轴对象。检查here。很方便的功能。 pd_dataframe.plot().tick_params(axis='x', labelrotation=90).
      • 唯一的问题是,如果使用 labelrotation=30 之类的东西,我无法弄清楚如何正确水平对齐标签。
      【解决方案11】:

      这里有很多“正确”的答案,但我会再添加一个,因为我认为一些细节被忽略了。 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_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(如plt),但它是面向对象的,因为我们正在更改特定ax 对象的属性。

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

      选项 6

      这个选项很简单,但是 AFAIK 你不能这样设置标签水平对齐,所以如果你的角度不是 90,另一个选项可能会更好。

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

      编辑: 讨论了这个确切的“错误”,但尚未发布修复程序(截至3.4.0): https://github.com/matplotlib/matplotlib/issues/13774

      【讨论】:

      • 可以添加到选项 2:fig = plt.gcf() - 很好的答案顺便说一句,它对我帮助很大。
      • 另外,选项 6 错误在v3.4.0 中仍然仍然存在
      • 选项 3a、3b 似乎已停产:它们引发了 UserWarning(这个:stackoverflow.com/questions/63723514
      【解决方案12】:

      将x轴标签旋转90度

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

      【讨论】:

      • 我喜欢你的答案有多短,但你发布的不是有效的 Python 代码。我不清楚如何将其解释为有效的 python 代码。
      【解决方案13】:

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

      plt.xticks(rotation=XX)
      

      还有

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-06-30
        • 2017-02-14
        相关资源
        最近更新 更多