Matplotlib 中的日期精度和纪元

Beginner

This tutorial is from open-source community. Access the source code

简介

这是一个循序渐进的实验,展示了如何在 Matplotlib 中处理日期精度和纪元。Matplotlib 可以使用一个识别这些日期并将其转换为浮点数的单位转换器来处理.datetime对象和numpy.datetime64对象。在 Matplotlib 3.3 之前,这种转换的默认值返回一个自“0000-12-31T00:00:00”以来的天数的浮点数。从 Matplotlib 3.3 开始,默认值是自“1970-01-01T00:00:00”以来的天数。这为现代日期提供了更高的分辨率。

虚拟机提示

虚拟机启动完成后,点击左上角切换到“笔记本”标签,以访问 Jupyter Notebook 进行练习。

有时,你可能需要等待几秒钟让 Jupyter Notebook 完成加载。由于 Jupyter Notebook 的限制,操作的验证无法自动化。

如果你在学习过程中遇到问题,随时向 Labby 提问。课程结束后提供反馈,我们将立即为你解决问题。

导入必要的包

第一步是导入必要的包,包括datetimematplotlib.pyplotnumpy

import datetime
import matplotlib.pyplot as plt
import numpy as np
import matplotlib.dates as mdates

将纪元设置为旧的默认值

下一步是将纪元设置为旧的默认值,即自“0000-12-31T00:00:00”起的天数。这可以使用mdates.set_epoch方法来完成。

mdates.set_epoch('0000-12-31T00:00:00')

将 datetime 转换为 Matplotlib 日期

既然已经设置了纪元,我们就可以使用mdates.date2num函数将datetime对象转换为 Matplotlib 日期。

date1 = datetime.datetime(2000, 1, 1, 0, 10, 0, 12, tzinfo=datetime.timezone.utc)
mdate1 = mdates.date2num(date1)

对日期进行往返转换

然后,我们可以使用mdates.num2date函数对日期进行往返转换,以确保转换的准确性。

date2 = mdates.num2date(mdate1)

将纪元设置为新的默认值

为了使用微秒精度的现代日期,我们需要将纪元设置为新的默认值,即自“1970-01-01T00:00:00”起的天数。

mdates.set_epoch('1970-01-01T00:00:00')

使用新的纪元将 datetime 转换为 Matplotlib 日期

既然纪元已设置为新的默认值,我们就可以使用mdates.date2num函数将datetime对象转换为 Matplotlib 日期。

date1 = datetime.datetime(2020, 1, 1, 0, 10, 0, 12, tzinfo=datetime.timezone.utc)
mdate1 = mdates.date2num(date1)

使用新的纪元对日期进行往返转换

然后,我们可以使用mdates.num2date函数对日期进行往返转换,以确保转换的准确性。

date2 = mdates.num2date(mdate1)

将 numpy.datetime64 转换为 Matplotlib 日期

numpy.datetime64 对象在比 .datetime 对象大得多的时间范围内具有微秒精度。然而,目前,Matplotlib 时间仅转换回具有微秒分辨率且年份仅跨度为 0000 到 9999 的 datetime 对象。

date1 = np.datetime64('2000-01-01T00:10:00.000012')
mdate1 = mdates.date2num(date1)

绘图

此步骤展示了纪元如何影响绘图。使用旧的默认纪元时,在内部date2num转换过程中时间会被四舍五入,导致数据出现跳跃。

mdates.set_epoch('0000-12-31T00:00:00')

x = np.arange('2000-01-01T00:00:00.0', '2000-01-01T00:00:00.000100', dtype='datetime64[us]')
xold = np.array([mdates.num2date(mdates.date2num(d)) for d in x])
y = np.arange(0, len(x))

fig, ax = plt.subplots(layout='constrained')
ax.plot(xold, y)
ax.set_title('Epoch: ' + mdates.get_epoch())
ax.xaxis.set_tick_params(rotation=40)
plt.show()

对于使用更新的纪元绘制的日期,绘图是平滑的:

mdates.set_epoch('1970-01-01T00:00:00')

fig, ax = plt.subplots(layout='constrained')
ax.plot(x, y)
ax.set_title('Epoch: ' + mdates.get_epoch())
ax.xaxis.set_tick_params(rotation=40)
plt.show()

总结

本实验展示了如何在 Matplotlib 中处理日期精度和纪元。我们可以使用mdates.set_epoch方法将纪元设置为旧的默认值或新的默认值。然后,我们可以使用mdates.date2num函数将datetimenumpy.datetime64对象转换为 Matplotlib 日期,并使用mdates.num2date函数对日期进行往返转换,以确保转换的准确性。我们还可以绘制具有不同纪元的数据,以观察绘图中的差异。