matplotlib中的日期刻度和旋转

Nea*_*eal 141 python matplotlib

我有一个问题试图让我的日期刻度在matplotlib中旋转.下面是一个小样本程序.如果我尝试在末尾旋转刻度线,则刻度线不会旋转.如果我尝试旋转注释'崩溃'下显示的刻度,则matplot lib崩溃.

只有当x值是日期时才会发生这种情况.如果我用调用中dates的变量替换变量,则调用在内部工作正常.tavail_plotxticks(rotation=70)avail_plot

有任何想法吗?

import numpy as np
import matplotlib.pyplot as plt
import datetime as dt

def avail_plot(ax, x, y, label, lcolor):
    ax.plot(x,y,'b')
    ax.set_ylabel(label, rotation='horizontal', color=lcolor)
    ax.get_yaxis().set_ticks([])

    #crashes
    #plt.xticks(rotation=70)

    ax2 = ax.twinx()
    ax2.plot(x, [1 for a in y], 'b')
    ax2.get_yaxis().set_ticks([])
    ax2.set_ylabel('testing')

f, axs = plt.subplots(2, sharex=True, sharey=True)
t = np.arange(0.01, 5, 1)
s1 = np.exp(t)
start = dt.datetime.now()
dates=[]
for val in t:
    next_val = start + dt.timedelta(0,val)
    dates.append(next_val)
    start = next_val

avail_plot(axs[0], dates, s1, 'testing', 'green')
avail_plot(axs[1], dates, s1, 'testing2', 'red')
plt.subplots_adjust(hspace=0, bottom=0.3)
plt.yticks([0.5,],("",""))
#doesn't crash, but does not rotate the xticks
#plt.xticks(rotation=70)
plt.show()
Run Code Online (Sandbox Code Playgroud)

cge*_*cge 216

如果您更喜欢非面向对象的方法,请在两次avail_plot调用之前将plt.xticks(rotation = 70)移到右侧,例如

plt.xticks(rotation=70)
avail_plot(axs[0], dates, s1, 'testing', 'green')
avail_plot(axs[1], dates, s1, 'testing2', 'red')
Run Code Online (Sandbox Code Playgroud)

这会在设置标签之前设置rotation属性.由于这里有两个轴,因此在制作完两个图之后,plt.xticks会变得混乱.而此时plt.xticks不会做任何事情的地步,plt.gca()并没有给你作用于当前坐标要修改的轴,所以plt.xticks,是行不通的.

对于不使用plt.xticks的面向对象方法,您可以使用

plt.setp( axs[1].xaxis.get_majorticklabels(), rotation=70 )
Run Code Online (Sandbox Code Playgroud)

两次avail_plot调用之后.这样就可以在正确的轴上设置旋转.

  • 我不喜欢这个解决方案,因为它混合了pyplot和面向对象的方法.你可以在任何地方调用`ax.tick_params(axis ='x',rotation = 70)`. (15认同)
  • 另一个方便的事情是:当你调用`plt.setp`时,你可以通过将它们指定为附加的关键字参数来设置多个参数.当你旋转刻度标签时,`horizo​​ntalalignment` kwarg特别有用:`plt.setp(axs [1] .xaxis.get_majorticklabels(),rotation = 70,horizo​​ntalalignment ='right')` (10认同)
  • @TedPetrou这里的"混音"是什么意思?`plt.setp`解决方案完全面向对象.如果你不喜欢其中有一些`plt`的事实,请使用`from matplotlib.artist import setp; setp(ax.get_xticklabels(),rotation = 90)`而不是. (2认同)

Ted*_*rou 78

解决方案适用于matplotlib 2.1+

存在tick_params可以改变刻度属性的轴方法.它也作为轴方法存在set_tick_params

ax.tick_params(axis='x', rotation=45)
Run Code Online (Sandbox Code Playgroud)

要么

ax.xaxis.set_tick_params(rotation=45)
Run Code Online (Sandbox Code Playgroud)

作为旁注,当前的解决方案通过使用命令将状态接口(使用pyplot)与面向对象的接口混合plt.xticks(rotation=70).由于问题中的代码使用面向对象的方法,因此最好始终坚持使用该方法.该解决方案确实提供了一个很好的显式解决方plt.setp( axs[1].xaxis.get_majorticklabels(), rotation=70 )


Imp*_*est 37

避免在ticklabes上循环的简单解决方案就是使用

fig.autofmt_xdate()

此命令自动旋转xaxis标签并调整其位置.默认值是旋转角度30°和水平对齐"右".但是它们可以在函数调用中更改

fig.autofmt_xdate(bottom=0.2, rotation=30, ha='right')
Run Code Online (Sandbox Code Playgroud)

附加bottom参数等同于设置plt.subplots_adjust(bottom=bottom),它允许将底轴填充设置为更大的值以托管旋转的勾选标签.

所以基本上你可以在一个命令中拥有一个漂亮的日期轴所需的所有设置.

在matplotlib页面上可以找到一个很好的例子.


Pab*_*yes 14

应用horizontalalignmentrotation每个tick标签的另一种方法是在for要更改的tick标签上执行循环:

import numpy as np
import matplotlib.pyplot as plt
import datetime as dt

now = dt.datetime.now()
hours = [now + dt.timedelta(minutes=x) for x in range(0,24*60,10)]
days = [now + dt.timedelta(days=x) for x in np.arange(0,30,1/4.)]
hours_value = np.random.random(len(hours))
days_value = np.random.random(len(days))

fig, axs = plt.subplots(2)
fig.subplots_adjust(hspace=0.75)
axs[0].plot(hours,hours_value)
axs[1].plot(days,days_value)

for label in axs[0].get_xmajorticklabels() + axs[1].get_xmajorticklabels():
    label.set_rotation(30)
    label.set_horizontalalignment("right")
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

如果你想控制主要和次要刻度的位置,这里有一个例子:

import numpy as np
import matplotlib.pyplot as plt
import datetime as dt

fig, axs = plt.subplots(2)
fig.subplots_adjust(hspace=0.75)
now = dt.datetime.now()
hours = [now + dt.timedelta(minutes=x) for x in range(0,24*60,10)]
days = [now + dt.timedelta(days=x) for x in np.arange(0,30,1/4.)]

axs[0].plot(hours,np.random.random(len(hours)))
x_major_lct = mpl.dates.AutoDateLocator(minticks=2,maxticks=10, interval_multiples=True)
x_minor_lct = matplotlib.dates.HourLocator(byhour = range(0,25,1))
x_fmt = matplotlib.dates.AutoDateFormatter(x_major_lct)
axs[0].xaxis.set_major_locator(x_major_lct)
axs[0].xaxis.set_minor_locator(x_minor_lct)
axs[0].xaxis.set_major_formatter(x_fmt)
axs[0].set_xlabel("minor ticks set to every hour, major ticks start with 00:00")

axs[1].plot(days,np.random.random(len(days)))
x_major_lct = mpl.dates.AutoDateLocator(minticks=2,maxticks=10, interval_multiples=True)
x_minor_lct = matplotlib.dates.DayLocator(bymonthday = range(0,32,1))
x_fmt = matplotlib.dates.AutoDateFormatter(x_major_lct)
axs[1].xaxis.set_major_locator(x_major_lct)
axs[1].xaxis.set_minor_locator(x_minor_lct)
axs[1].xaxis.set_major_formatter(x_fmt)
axs[1].set_xlabel("minor ticks set to every day, major ticks show first day of month")
for label in axs[0].get_xmajorticklabels() + axs[1].get_xmajorticklabels():
    label.set_rotation(30)
    label.set_horizontalalignment("right")
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述


Fra*_*ois 9

我显然迟到了,但有一个官方示例使用

plt.setp(ax.get_xticklabels(), rotation=45, ha="right", rotation_mode="anchor")
Run Code Online (Sandbox Code Playgroud)

旋转标签,同时保持它们与刻度线正确对齐,这既干净又简单。

参考: https: //matplotlib.org/stable/gallery/images_contours_and_fields/image_annotated_heatmap.html


giz*_*ole 6

只需使用

ax.set_xticklabels(label_list, rotation=45)
Run Code Online (Sandbox Code Playgroud)