使用matplotlib绘制以时间戳为x轴的图表
我有一段代码,用来用matplotlib画图。
#!/usr/bin/env python
import matplotlib.pyplot as plt
import urllib2
import json
req = urllib2.urlopen("http://localhost:17668/retrieval/data/getData.json? pv=LNLS:ANEL:corrente&donotchunk")
data = json.load(req)
secs = [x['secs'] for x in data[0]['data']]
vals = [x['val'] for x in data[0]['data']]
plt.plot(secs, vals)
plt.show()
这里的secs数组是时间戳,也就是从1970年1月1日开始的秒数。
我想把x轴的数据(secs)显示成日期格式(DD-MM-YYYY HH:MM:SS),也就是日-月-年 时:分:秒。
我该怎么做呢?
2 个回答
5
你可以改变图表上刻度的位置和格式:
import matplotlib.pyplot as plt
import matplotlib.ticker as mtick
import time
secs = [10928389,102928123,383827312,1238248395]
vals = [12,8,4,12]
plt.plot(secs,vals)
plt.gcf().autofmt_xdate()
plt.gca().xaxis.set_major_locator(mtick.FixedLocator(secs))
plt.gca().xaxis.set_major_formatter(
mtick.FuncFormatter(lambda pos,_: time.strftime("%d-%m-%Y %H:%M:%S",time.localtime(pos)))
)
plt.tight_layout()
plt.show()
29
在matplotlib中绘制基于日期的数据时,你需要把数据转换成正确的格式。
一种方法是先把你的数据转换成datetime
对象。如果你有一个时间戳,可以使用datetime.datetime.fromtimestamp()
来进行转换。
接下来,你需要把这些datetime
对象转换成matplotlib能识别的格式,这可以通过matplotlib.date.date2num
来完成。
另外,你也可以使用matplotlib.dates.epoch2num
,这样就可以跳过把日期转换成datetime
对象的步骤(虽然这样一开始可能更适合你的需求,但我建议尽量在工作时保持日期为datetime
对象,这样长远来看会省去很多麻烦)。
一旦你的数据格式正确,就可以使用plot_date
来绘制它。
最后,如果你想自定义x轴的格式,可以使用matplotlib.dates.DateFormatter
对象来选择刻度的显示方式。
import matplotlib.pyplot as plt
import matplotlib.dates as mdate
import numpy as np
# Generate some random data.
N = 40
now = 1398432160
raw = np.array([now + i*1000 for i in range(N)])
vals = np.sin(np.linspace(0,10,N))
# Convert to the correct format for matplotlib.
# mdate.epoch2num converts epoch timestamps to the right format for matplotlib
secs = mdate.epoch2num(raw)
fig, ax = plt.subplots()
# Plot the date using plot_date rather than plot
ax.plot_date(secs, vals)
# Choose your xtick format string
date_fmt = '%d-%m-%y %H:%M:%S'
# Use a DateFormatter to set the data to the correct format.
date_formatter = mdate.DateFormatter(date_fmt)
ax.xaxis.set_major_formatter(date_formatter)
# Sets the tick labels diagonal so they fit easier.
fig.autofmt_xdate()
plt.show()