如何更改pandas.plot的x轴刻度频率

29
我正在使用pandas的.plot()函数绘制时间序列,并希望将每个月显示为x轴刻度。
以下是数据集的结构: data set 这是.plot()函数的结果。

enter image description here

我试图使用其他帖子和matplotlib的示例文档,并尝试做类似的事情。
ax.xaxis.set_major_locator(
   dates.MonthLocator(revenue_pivot.index, bymonthday=1,interval=1))

但是这样移除了所有的刻度 :(
我还尝试了传递 xticks = df.index,但是没有改变任何东西。
如何正确地显示更多的 x 轴刻度?

1
你正在将日期解析为日期时间吗? - Demetri Pananos
@DemetriP 谢谢。看起来它至少是问题的一部分。现在使用 ax.xaxis.set_major_locator 后,我确实看到刻度线...唯一的问题是现在每年只有一个刻度线。 我明显是错误地使用了 MonthLocator。 - Rotkiv
5个回答

34

不需要向MonthLocator传递任何参数。请确保在df.plot()调用中使用x_compat,根据@Rotkiv的回答。

import pandas as pd
import numpy as np
import matplotlib.pylab as plt
import matplotlib.dates as mdates

df = pd.DataFrame(np.random.rand(100,2), index=pd.date_range('1-1-2018', periods=100))
ax = df.plot(x_compat=True)
ax.xaxis.set_major_locator(mdates.MonthLocator())
plt.show()
  • 使用 set_major_locator 格式化 x 轴

enter image description here

  • x 轴未经格式化

enter image description here


12

您还可以使用 pandas 的 Timestamp 对象的属性 “手动” 格式化 pandas DateTimeIndex 的 x 轴刻度和标签。

我发现这比使用来自 matplotlib.dates 的定位器要容易得多,后者适用于不同于 pandas 的其他日期时间格式,因此如果未相应转换日期,则有时会表现出奇怪的行为。

以下是一个通用示例,它显示了以 pandas Timestamp 对象的属性为基础的每个月第一天作为标签:

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt


# data
dim = 8760
idx = pd.date_range('1/1/2000 00:00:00', freq='h', periods=dim)
df = pd.DataFrame(np.random.randn(dim, 2), index=idx)

# select tick positions based on timestamp attribute logic. see:
# https://pandas.pydata.org/pandas-docs/stable/generated/pandas.Timestamp.html
positions = [p for p in df.index
             if p.hour == 0
             and p.is_month_start
             and p.month in range(1, 13, 1)]
# for date formatting, see:
# https://docs.python.org/2/library/datetime.html#strftime-and-strptime-behavior
labels = [l.strftime('%m-%d') for l in positions]

# plot with adjusted labels
ax = df.plot(kind='line', grid=True)
ax.set_xlabel('Time (h)')
ax.set_ylabel('Foo (Bar)')
ax.set_xticks(positions)
ax.set_xticklabels(labels)

plt.show()
产生的结果为:

产出:

在此输入图片描述

希望这有所帮助!


4
正确的方法如下描述:在这里 使用x_compat参数可以抑制自动刻度分辨率调整。 df.A.plot(x_compat=True)

4
对我来说不起作用。Python版本为3.6,pandas版本为0.19.2。有任何想法是为什么? - famargar
3
我也不是,Python 3.6和Pandas 0.22。 - seanysull
1
@seanysull,如果有确切的信息,应该很容易解决。不幸的是,这个问题没有提供 MCVE,所以很难确定你的数据框等是否设置与 OPs 相同(因为 OP 自己回答说他们可能在“幕后”做了一些事情来解决问题)。我个人会提出另一个问题,链接到这个问题,解释为什么这对你不起作用。 - DavidG

0

移除刻度标签:

ax = df.plot(x='date', y=['count'])
every_nth = 10
for n, label in enumerate(ax.xaxis.get_ticklabels()):
  if n % every_nth != 0:
    label.set_visible(False)

every_nth降低以包含更多标签,提高以保留较少的标签。


0

如果你只想展示更多的刻度,你也可以深入 pd.plotting._converter 的结构中:

dai = ax.xaxis.minor.formatter.plot_obj.date_axis_info
dai['fmt'][dai['fmt'] == b''] = b'%b'

绘图后,formatter 是一个 TimeSeries_DateFormatter,并且已经调用了 _set_default_format,因此 self.plot_obj.date_axis_info is not None。现在,您可以操纵结构化数组 .date_axis_info,使其符合您的喜好,即包含更少的 b'' 和更多的 b'%b'

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接