Pandas 时间序列图设置 x 轴主刻度和次刻度以及标签

2025-02-13 08:36:00
admin
原创
50
摘要:问题描述:我希望能够为从 Pandas 时间序列对象绘制的时间序列图设置主 xticks 和次 xticks 及其标签。Pandas 0.9 的“新功能”页面显示:“您可以使用 to_pydatetime 或为 Timestamp 类型注册一个转换器”但我不知道如何做到这一点,以便我可以使用 matplotl...

问题描述:

我希望能够为从 Pandas 时间序列对象绘制的时间序列图设置主 xticks 和次 xticks 及其标签。

Pandas 0.9 的“新功能”页面显示:

“您可以使用 to_pydatetime 或为 Timestamp 类型注册一个转换器”

但我不知道如何做到这一点,以便我可以使用 matplotlibax.xaxis.set_major_locatorax.xaxis.set_major_formatter(和次要)命令。

如果我在不转换熊猫时间的情况下使用它们,x 轴刻度和标签最终会出错。

通过使用 'xticks' 参数,我可以将主刻度传递给 pandas' .plot,然后设置主刻度标签。我无法弄清楚如何使用这种方法来设置小刻度(我可以在 pandas' 设置的默认小刻度上设置标签.plot)。

这是我的测试代码:

图表 xaxis 上有奇怪的日期
import pandas as pd
import matplotlib.dates as mdates
import numpy as np

dateIndex = pd.date_range(start='2011-05-01', end='2011-07-01', freq='D')
testSeries = pd.Series(data=np.random.randn(len(dateIndex)), index=dateIndex)    

ax = plt.figure(figsize=(7,4), dpi=300).add_subplot(111)
testSeries.plot(ax=ax, style='v-', label='first line')    

# using MatPlotLib date time locators and formatters doesn't work with new
# pandas datetime index
ax.xaxis.set_minor_locator(mdates.WeekdayLocator())
ax.xaxis.set_minor_formatter(mdates.DateFormatter('%d
%a'))
ax.xaxis.grid(True, which="minor")
ax.xaxis.grid(False, which="major")
ax.xaxis.set_major_formatter(mdates.DateFormatter('


%b%Y'))
plt.show()    

图表 xaxis 上有奇怪的日期

带有正确日期的图表(无小刻度)
# set the major xticks and labels through pandas
ax2 = plt.figure(figsize=(7,4), dpi=300).add_subplot(111)
xticks = pd.date_range(start='2011-05-01', end='2011-07-01', freq='W-Tue')
testSeries.plot(ax=ax2, style='-v', label='second line', xticks=xticks.to_pydatetime())
ax2.set_xticklabels([x.strftime('%a
%d
%h
%Y') for x in xticks]);
# remove the minor xtick labels set by pandas.plot 
ax2.set_xticklabels([], minor=True)
# turn the minor ticks created by pandas.plot off 
plt.show()

带有正确日期的图表

更新:通过使用循环构建主要的 xtick 标签,我已经能够更接近我想要的布局:

# only show month for first label in month
month = dStart.month - 1
xticklabels = []
for x in xticks:
    if  month != x.month :
        xticklabels.append(x.strftime('%d
%a
%h'))
        month = x.month
    else:
        xticklabels.append(x.strftime('%d
%a'))

但是,这有点像使用 x 轴ax.annotate:可行但并不理想。

绘制熊猫时间序列数据时,如何设置主刻度和次刻度?


解决方案 1:

pandas和都matplotlib.dates用于matplotlib.units定位蜱虫。

但是,尽管matplotlib.dates有方便的方法来手动设置刻度,但到目前为止,pandas 似乎仍专注于自动格式化(您可以查看pandas 中日期转换和格式化的代码)。

因此目前看来使用它更为合理matplotlib.dates(正如@BrenBarn 在他的评论中提到的)。

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

idx = pd.date_range('2011-05-01', '2011-07-01')
s = pd.Series(np.random.randn(len(idx)), index=idx)

fig, ax = plt.subplots()
ax.plot_date(idx.to_pydatetime(), s, 'v-')
ax.xaxis.set_minor_locator(dates.WeekdayLocator(byweekday=(1),
                                                interval=1))
ax.xaxis.set_minor_formatter(dates.DateFormatter('%d
%a'))
ax.xaxis.grid(True, which="minor")
ax.yaxis.grid()
ax.xaxis.set_major_locator(dates.MonthLocator())
ax.xaxis.set_major_formatter(dates.DateFormatter('


%b
%Y'))
plt.tight_layout()
plt.show()

pandas_like_date_fomatting 复制代码

(我的语言环境是德语,因此星期二 [Tue] 变成了 Dienstag [Di])

解决方案 2:

要关闭 Pandas Datetime 刻度调整,必须添加参数x_compat=True

例子:

ds.plot(x_compat=True)

请参阅 Pandas 文档中的更多示例:抑制刻度分辨率调整

解决方案 3:

在matplotlib中plot(),默认的时间序列单位是1天,而在pandas中plot(),1个单位等于时间序列的频率,所以如果频率是1天,那么1个单位就是1天;如果是1小时,那么1个单位就是1小时等等。这使得plot()matplotlib和pandas在处理时间序列数据时的调用有所不同。

如果时间序列的频率是1天,那么matplotlib.dates.WeekdayLocatormatplotlib.dates.MonthLocator可以“定位”刻度位置1,因为1天是pandas使用1天作为基本单位来制作xtick位置plot()(与matplotlib的默认值一致)。

由于 pandas 的plot()调用返回一个 Axes 对象,因此可以使用 来修改该 Axes 对象的刻度标签matplotlib.dates

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

idx = pd.date_range('2011-05-01', '2011-07-01', freq='D')
s1 = pd.Series(np.random.randn(len(idx)), index=idx)

ax = s1.plot(style='v-')
ax.xaxis.set(
    minor_locator=mdates.WeekdayLocator(),               # make minor ticks on each Tuesday
    minor_formatter=mdates.DateFormatter('%d
%a'),      # format minor ticks
    major_locator=mdates.MonthLocator(),                 # make major ticks on first day of each month
    major_formatter=mdates.DateFormatter('


%b
%Y') # format major ticks
);

第一张图片


但是,如果频率不是 1 天,而是 1 周,那么matplotlib.dates将无法定位位置,因为如前所述,pandasplot()将单位设置为与时间序列频率(1 周)相同,这会“混淆” matplotlib.dates。因此,如果我们尝试使用用于设置刻度标签的相同代码s1来设置刻度标签s2,那么我们将得到非常错误的刻度标签。

要“解决”该问题,一种方法是通过传递来删除 pandas 的自动刻度分辨率调整x_compat=True。然后可以使用 matplotlib 的分辨率设置主/次刻度标签;换句话说,可以按照与上述相同的方式进行设置。

idx = pd.date_range('2011-05-01', '2011-07-01', freq='W')
s2 = pd.Series(np.random.randn(len(idx)), index=idx)

ax = s2.plot(style='v-', x_compat=True, rot=0)
ax.xaxis.set(
    minor_locator=mdates.WeekdayLocator(),              # make minor ticks on each Tuesday
    minor_formatter=mdates.DateFormatter('%d'),         # format minor ticks
    major_locator=mdates.MonthLocator(),                # make major ticks on first day of each month
    major_formatter=mdates.DateFormatter('

%b
%Y')  # format major ticks
);

第二张图片

解决该问题的另一种方法是改用 matplotlib (如@bmuplot()所建议)。由于单位在 matplotlib 中是固定的,因此我们可以像上面一样设置刻度标签而不会出现问题。

plt.plot(s2.index, s2, 'v-')                            # use matplotlib instead
plt.gca().xaxis.set(
    minor_locator=mdates.WeekdayLocator(byweekday=0),   # make minor ticks on each Monday
    minor_formatter=mdates.DateFormatter('%d'),         # format minor ticks
    major_locator=mdates.MonthLocator(),                # make major ticks on first day of each month
    major_formatter=mdates.DateFormatter('

%b
%Y')  # format major ticks
);

1 matplotlib.dates.num2timedelta(1) == datetime.timedelta(days=1)为真。

相关推荐
  政府信创国产化的10大政策解读一、信创国产化的背景与意义信创国产化,即信息技术应用创新国产化,是当前中国信息技术领域的一个重要发展方向。其核心在于通过自主研发和创新,实现信息技术应用的自主可控,减少对外部技术的依赖,并规避潜在的技术制裁和风险。随着全球信息技术竞争的加剧,以及某些国家对中国在科技领域的打压,信创国产化显...
工程项目管理   1565  
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1354  
  信创国产芯片作为信息技术创新的核心领域,对于推动国家自主可控生态建设具有至关重要的意义。在全球科技竞争日益激烈的背景下,实现信息技术的自主可控,摆脱对国外技术的依赖,已成为保障国家信息安全和产业可持续发展的关键。国产芯片作为信创产业的基石,其发展水平直接影响着整个信创生态的构建与完善。通过不断提升国产芯片的技术实力、产...
国产信创系统   21  
  信创生态建设旨在实现信息技术领域的自主创新和安全可控,涵盖了从硬件到软件的全产业链。随着数字化转型的加速,信创生态建设的重要性日益凸显,它不仅关乎国家的信息安全,更是推动产业升级和经济高质量发展的关键力量。然而,在推进信创生态建设的过程中,面临着诸多复杂且严峻的挑战,需要深入剖析并寻找切实可行的解决方案。技术创新难题技...
信创操作系统   27  
  信创产业作为国家信息技术创新发展的重要领域,对于保障国家信息安全、推动产业升级具有关键意义。而国产芯片作为信创产业的核心基石,其研发进展备受关注。在信创国产芯片的研发征程中,面临着诸多复杂且艰巨的难点,这些难点犹如一道道关卡,阻碍着国产芯片的快速发展。然而,科研人员和相关企业并未退缩,积极探索并提出了一系列切实可行的解...
国产化替代产品目录   28  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用