python中xticks函数中rotation_关于python:matplotlib中的日期刻度和旋转

在matplotlib中绘制带有日期的图表时,遇到日期刻度旋转的问题。代码示例显示了在不同位置设置`xticks(rotation=70)`时的行为,包括导致程序崩溃的情况。解决方案包括使用`ax.tick_params`或`plt.setp`方法来专门设置轴的刻度标签旋转,以避免混淆matplotlib的pyplot和面向对象接口。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

我在尝试在matplotlib中旋转日期刻度时遇到问题。 下面是一个小示例程序。 如果我尝试最后旋转刻度线,则刻度线不会旋转。 如果我尝试如注释" crashes"下所示旋转刻度线,则matplot lib崩溃。

仅当x值为日期时,才会发生这种情况。 如果在对avail_plot的调用中将变量dates替换为变量t,则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()

创建一个在x轴上带有日期的图是一项常见的任务-可惜那里没有更完整的示例。

我想知道这是否不是stackoverflow.com/questions/10998621/的副本

如果您喜欢非面向对象的方法,请在两个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')

这将在设置标签之前设置旋转属性。由于这里有两个轴,因此在绘制两个图后plt.xticks会感到困惑。当plt.xticks不执行任何操作时,plt.gca()不会为您提供要修改的轴,因此作用于当前轴的plt.xticks将无法工作。

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

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

在两个avail_plot调用之后。这样可以专门设置正确轴上的旋转。

另一件方便的事:调用plt.setp时,可以通过将多个参数指定为其他关键字参数来设置多个参数。当旋转刻度线标签时,horizontalalignment kwarg特别有用:plt.setp( axs[1].xaxis.get_majorticklabels(), rotation=70, horizontalalignment=right )

我不喜欢这种解决方案,因为它混合了pyplot和面向对象的方法。您可以在任何地方调用ax.tick_params(axis=x, rotation=70)。

@TedPetrou您在这里"混合"是什么意思? plt.setp解决方案完全是面向对象的。如果您不喜欢其中包含某些plt的事实,请改用from matplotlib.artist import setp; setp(ax.get_xticklabels(), rotation=90)。

@ImportanceOfBeingErnest代码的第一行使用plt.xticks,即pyplot。文档本身说不要混合样式。 plt.setp更冗长,但也不是典型的面向对象样式。您的答案肯定是最好的。基本上,任何具有功能的东西都不是面向对象的。是否导入setp都没有关系。

代码中的许多问题都使用pyplot,例如yticks,并且代码在avail_plot之外完全没有定义ax。

@cge否。他用面向对象的方法f, axs = plt.subplots(2, sharex=True, sharey=True)明确地开始了问题。除了plt.show之外,还有另外两个对plt的调用,因此我不会说很多代码都使用pyplot。 setp解决方案实际上是好的且明确的。 plt.xticks不是。

这对绘图没有任何影响,但是fig.autofmt_xdate(bottom = 0.2,rotation = 30,ha = right)帮助了!

设置刻度rotation时,您可能还希望设置horizontalalignment,例如plt.xticks(rotation=45, horizontalalignment=right)

解决方案适用于Matplotlib 2.1+

存在一个可以更改刻度属性的轴方法tick_params。它也作为set_tick_params的轴方法存在

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

要么

ax.xaxis.set_tick_params(rotation=45)

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

一个简单的解决方案是使用

fig.autofmt_xdate()

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

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

附加的bottom自变量等效于设置plt.subplots_adjust(bottom=bottom),它允许将底部轴填充设置为较大的值,以承载旋转的刻度标签。

因此,基本上,这里您具有所有必要的设置,只需一个命令即可拥有一个漂亮的日期轴。

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

好答案!谢谢!

将horizontalalignment和rotation应用于每个刻度标签的另一种方法是对要更改的刻度标签执行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 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")

这是一个示例,如果您想控制主要和次要刻度线的位置:

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

这在matplotlib v1.5.1上对我有用(我在使用matplotlib的旧版本时遇到问题,不要问为什么)

我刚刚使用python3.6和matplotlib v2.2.2进行了测试,它也可以工作。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值