在matplotlib中绘制Unix时间戳

62 投票
2 回答
118982 浏览
提问于 2025-04-16 06:30

我想用Python的matplotlib模块制作一个通用的值与时间的图表。我的时间是用Unix时间格式表示的,但我希望在图表的横轴上显示成易读的格式。

我看过一些关于使用日期时间对象绘图的回答,但这种方法似乎会去掉小时、分钟和秒的信息,只显示完整的日期。有没有办法生成这样的图表,并显示更详细的标签呢?

2 个回答

0

来自这里:https://matplotlib.org/stable/api/dates_api.html#matplotlib.dates.DateFormatter

import datetime
import matplotlib.dates as mdates

base = datetime.datetime(2005, 2, 1)
dates = np.array([base + datetime.timedelta(hours=(2 * i))
                  for i in range(732)])
N = len(dates)
np.random.seed(19680801)
y = np.cumsum(np.random.randn(N))

fig, ax = plt.subplots(constrained_layout=True)
locator = mdates.AutoDateLocator()
formatter = mdates.ConciseDateFormatter(locator)
ax.xaxis.set_major_locator(locator)
ax.xaxis.set_major_formatter(formatter)

ax.plot(dates, y)
ax.set_title('Concise Date Formatter')
98

你可以用 plt.plot(dates,values) 来绘图,其中 dates 是一个包含 datetime.datetime 对象的列表。这样绘制出来的图会在x轴上显示日期,格式像 '%Y-%m-%d',而当你放大图的时候,它会自动调整为显示小时、分钟和秒。

不过,听起来你想要更多的控制权。也许它显示的小时、分钟和秒并不是你想要的那种比例。

在这种情况下,你可以自己设置日期的格式:

ax=plt.gca()
xfmt = md.DateFormatter('%Y-%m-%d %H:%M:%S')
ax.xaxis.set_major_formatter(xfmt)

不过,如果你直接把 datetime.datetime 对象传给 plt.plot,那么matplotlib自动选择的x轴刻度似乎总是把秒数设为零。比如,如果你运行

import matplotlib.pyplot as plt
import matplotlib.dates as md
import numpy as np
import datetime as dt
import time

n=20
duration=1000
now=time.mktime(time.localtime())
timestamps=np.linspace(now,now+duration,n)
dates=[dt.datetime.fromtimestamp(ts) for ts in timestamps]
values=np.sin((timestamps-now)/duration*2*np.pi)
plt.subplots_adjust(bottom=0.2)
plt.xticks( rotation=25 )
ax=plt.gca()
xfmt = md.DateFormatter('%Y-%m-%d %H:%M:%S')
ax.xaxis.set_major_formatter(xfmt)
plt.plot(dates,values)
plt.show()

alt text

你会得到格式不错的日期,但所有的x轴刻度的秒数都是零。

那么解决办法是什么呢?

如果你把时间戳转换成 datetime.datetime 对象,再转换成matplotlib的日期数字,然后把这些日期数字传给 plt.plot,那么秒数就会被保留。

附注:这里说的“matplotlib日期数字”是指通过 matplotlib.dates.date2num 返回的那种数字。

import matplotlib.pyplot as plt
import matplotlib.dates as md
import numpy as np
import datetime as dt
import time

n=20
duration=1000
now=time.mktime(time.localtime())
timestamps=np.linspace(now,now+duration,n)
dates=[dt.datetime.fromtimestamp(ts) for ts in timestamps]
datenums=md.date2num(dates)
values=np.sin((timestamps-now)/duration*2*np.pi)
plt.subplots_adjust(bottom=0.2)
plt.xticks( rotation=25 )
ax=plt.gca()
xfmt = md.DateFormatter('%Y-%m-%d %H:%M:%S')
ax.xaxis.set_major_formatter(xfmt)
plt.plot(datenums,values)
plt.show()

alt text

撰写回答