使用自定义开始/结束日期日期时间、matplotlib显示多年数据

2024-09-30 03:23:35 发布

您现在位置:Python中文网/ 问答频道 /正文

我觉得这个问题有一个明显的答案,我只是有点傻。假设您有两个带有日期时间索引的数据帧,其中每个数据帧用于不同的年份。就我而言,该指数每天从6月25日持续到次年6月24日:

date        var
2019-06-25  107.230294
2019-06-26  104.110004
2019-06-27  104.291506
2019-06-28  111.162552
2019-06-29  112.515364
...
2020-06-20  132.840242
2020-06-21  127.641148
2020-06-22  132.797584
2020-06-23  129.094451
2020-06-24  110.408866

我想要的是一个有多条线的单一地块,每条线代表一年。y轴是我的变量var,x轴应该是一年中的某一天。x轴应该从6月25日开始,到6月24日结束

这是我到目前为止尝试过的,但是它弄乱了x轴。有人知道更优雅的方法吗

fig, ax = plt.subplots()
plt.plot(average_prices19.index.strftime("%d/%m"), average_prices19.var, label = "2019-20")
plt.plot(average_prices20.index.strftime("%d/%m"), average_prices20.var, label = "2020-21")
plt.legend()
plt.show()

enter image description here


Tags: 数据答案dateindexplotvar时间plt
1条回答
网友
1楼 · 发布于 2024-09-30 03:23:35

好吧,这个问题有一个转折点:一年中的日期列表不是恒定的:在闰年中有一个'Feb-29'在其他方面是不存在的

如果您能够轻松地掩饰这一点(并且始终在绘图上表示一个潜在的'Feb-29'日期,并且缺少非闰年的数据),那么以下内容将实现您所寻求的(假设数据在df中,日期为DateTimeIndex):

import matplotlib.dates as mdates

fig, ax = plt.subplots()
for label, dfy in df.assign(
    # note: 2000 is a leap year; the choice is deliberate
    date=pd.to_datetime(df.index.strftime('2000-%m-%d')),
    label=df.index.strftime('%Y')
).groupby('label'):
    dfy.set_index('date')['var'].plot(ax=ax, label=str(label))
ax.xaxis.set_major_formatter(mdates.DateFormatter("%m-%d"))
ax.legend()

更新

但是,对于较大数量的数据,上述内容不会产生非常清晰的XLabel。因此,我们可以使用^{}定制xlabel的显示(并删除2000年):

import matplotlib.dates as mdates

fig, ax = plt.subplots()
for label, dfy in df.assign(
    # note: 2000 is a leap year; the choice is deliberate
    date=pd.to_datetime(df.index.strftime('2000-%m-%d')),
    label=df.index.strftime('%Y')
).groupby('label'):
    dfy.set_index('date')['var'].plot(ax=ax, label=str(label))
ax.legend()

locator = mdates.AutoDateLocator(minticks=3, maxticks=7)
formatter = mdates.ConciseDateFormatter(
    locator,
    formats=['', '%b', '%d', '%H:%M', '%H:%M', '%S.%f'],
    offset_formats=['', '', '%b', '%b-%d', '%b-%d', '%b-%d %H:%M']
)
ax.xaxis.set_major_locator(locator)
ax.xaxis.set_major_formatter(formatter)

对于示例中的数据:

有关更多数据:

# setup
idx = pd.date_range('2016-01-01', 'now', freq='QS')
df = pd.DataFrame(
    {'var': np.random.uniform(size=len(idx))},
    index=idx).resample('D').interpolate(method='polynomial', order=5)

相应的绘图(带有ConciseFormatter):

相关问题 更多 >

    热门问题