gpt4 book ai didi

python - 绘制不同频率的时间数据(matplotlib、pandas)

转载 作者:行者123 更新时间:2023-11-30 22:15:43 25 4
gpt4 key购买 nike

我正在尝试将 Pandas 时间序列和多个垂直段(标记)组合在同一个图中。该系列的频率为“Q-DEC”(季度),在本例中是根据日期推断的,但在实际问题中是数据集的一部分。标记通常与系列不一致,可能出现在任何地方,不一定出现在季度末。

我的问题是,如果我首先绘制系列,然后绘制标记,则标记的位置将向上舍入到季度的下一个末尾(上图)。如果我先绘制标记,然后绘制系列,则标记位于正确的位置,但 x 刻度标签不合适(下图)。

:如何在时间序列图上的正确位置绘制标记?

import datetime
import pandas as pd
from pandas import Timestamp
import matplotlib.pyplot as plt

data = pd.DataFrame({0: {Timestamp('2017-03-31'): 1,
Timestamp('2017-06-30'): 2,
Timestamp('2017-09-30'): 3,
Timestamp('2017-12-31'): 3,
Timestamp('2018-03-31'): 2,
Timestamp('2018-06-30'): 1}})

ax = plt.subplot(2,1,1)
data[0].plot(ax=ax,style="-mo")
ax.axvline(pd.Timestamp(datetime.date(2017, 7, 1)), c='r')
ax.axvline(pd.Timestamp(datetime.date(2017, 8, 10)), c='g')
ax.axvline(pd.Timestamp(datetime.date(2017, 9, 20)), c='b')
ax.axvline(pd.Timestamp(datetime.date(2017, 11, 30)), c='k')
ax = plt.subplot(2,1,2)
ax.axvline(pd.Timestamp(datetime.date(2017, 7, 1)), c='r')
ax.axvline(pd.Timestamp(datetime.date(2017, 8, 10)), c='g')
ax.axvline(pd.Timestamp(datetime.date(2017, 9, 20)), c='b')
ax.axvline(pd.Timestamp(datetime.date(2017, 11, 30)), c='k')
data[0].plot(ax=ax,style="-mo")
plt.show()

Example

最佳答案

如果将日期作为 PeriodIndex 移动到索引中,从 freq="M" 开始,以确保正确绘制线条。
然后将刻度替换为设置为 freq="Q-DEC" 的索引值。

data.set_index(pd.PeriodIndex(data.index, freq="M"), inplace=True)
ax = data[0].plot(style="-mo")

ax.axvline(pd.Timestamp(datetime.date(2017, 7, 1)), c='r')
ax.axvline(pd.Timestamp(datetime.date(2017, 8, 10)), c='g')
ax.axvline(pd.Timestamp(datetime.date(2017, 9, 20)), c='b')
ax.axvline(pd.Timestamp(datetime.date(2017, 11, 30)), c='k')

现在重置刻度:

q_ticks = data.index.asfreq("Q-DEC")
ax.minorticks_off()
ax.set_xticks(q_ticks)
ax.set_xticklabels(q_ticks)

输出:

enter image description here

注意:如果您不使用 minorticks_off() 删除次要刻度,则会与原始每月刻度和新的季度刻度有一些重叠。

更新
如果您确实需要完全获得示例中的格式,则需要对主要和次要刻度位置和格式进行一些操作:

ax.get_xaxis().set_tick_params(which='major', pad=15)

q_ticks = data.index.asfreq("Q-DEC")

# extract only the year, and only the year's first listing
major_ticklabels = pd.Series(q_ticks.strftime("%Y"))
major_ticklabels[major_ticklabels.duplicated()] = ""
ax.set_xticks(q_ticks)
ax.set_xticklabels(major_ticklabels)

# format as Q[quarter number]
minor_ticklabels = q_ticks.strftime("Q%q")
ax.xaxis.set_ticks(q_ticks, minor=True)
ax.xaxis.set_ticklabels(minor_ticklabels, minor=True)

enter image description here

关于python - 绘制不同频率的时间数据(matplotlib、pandas),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50206120/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com