dateticks和matplotlib中的旋转

我有一个问题试图让我的dateticks在matplotlib中旋转。 下面是一个小样本程序。 如果我试图在最后旋转刻度,则刻度不会旋转。 如果我尝试按照“崩溃”注释中所示旋转刻度,则matplot库会崩溃。

这只有在x值是date时才会发生。 如果我用avail_plot调用中的variablestreplacevariablesdates ,那么xticks(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() 

将plt.xticks(rotation = 70)移到两个avail_plot调用之前 ,例如

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

这将在设置标签之前设置旋转属性。 既然你在这里有两个坐标轴,我认为plt.xticks在你做了两个图之后会感到困惑。 看来在plt.xticks什么都不做的时候,plt.gca()不会给你想要修改的轴,所以plt.xticks在当前坐标轴上不起作用。

或者,例如,不使用plt.xticks,您可以使用

 plt.setp( axs[1].xaxis.get_majorticklabels(), rotation=70 ) 

两个avail_plot调用之后。

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

fig.autofmt_xdate()

该命令自动旋转xaxis标签并调整其位置。 默认值是旋转angular度30°和水平alignment“右”。 但是可以在函数调用中改变它们

 fig.autofmt_xdate(bottom=0.2, rotation=30, ha='right') 

额外的bottom参数相当于设置plt.subplots_adjust(bottom=bottom) ,它允许将底部轴填充设置为更大的值来承载旋转的标签。

所以基本上,在这里你有所有的设置,你需要有一个不错的date轴在一个命令。

一个很好的例子可以在matplotlib页面find。

horizontalalignmentrotation到每个刻度标签的另一种方法是for要更改的刻度标签执行for循环:

 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 np.arange(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") 

在这里输入图像说明

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

 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 np.arange(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") 

在这里输入图像说明

解决scheme适用于matplotlib 2.1+

存在可以更改刻度属性的坐标轴方法tick_params 。 它也以set_tick_params方式存在

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

要么

 ax.xaxis.set_tick_params(rotation=45) 

作为一个方面说明,当前的解决scheme使用命令plt.xticks(rotation=70)将有状态接口(使用pyplot)与面向对象的接口plt.xticks(rotation=70) 。 由于问题中的代码使用了面向对象的方法,所以最好始终坚持这种方法。 该解决scheme与plt.setp( axs[1].xaxis.get_majorticklabels(), rotation=70 )