python gnuplotpy 与日期时间
我一直在尝试用 gnuplot.py 打印以下数据:
data = [[datetime.datetime(2013, 1, 15, 17, 45), 16.00], [datetime.datetime(2013, 1, 16, 17, 45), 15.98], [datetime.datetime(2013, 1, 17, 17, 45), 15.94]]
所以我开始是这样做的:
gp=Gnuplot.Gnuplot()
gp('set data style linespoints')
gp('set xdata time')
gp('set timefmt "%Y-%m-%d"')
gp('set xrange ["2012-12-20":"2013-02-12"]')
gp.plot(data)
然后,我得到了以下的反馈:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python2.6/dist-packages/Gnuplot/_Gnuplot.py", line 285, in plot
self._add_to_queue(items)
File "/usr/lib/python2.6/dist-packages/Gnuplot/_Gnuplot.py", line 255, in _add_to_queue
self.itemlist.append(PlotItems.Data(item))
File "/usr/lib/python2.6/dist-packages/Gnuplot/PlotItems.py", line 549, in Data
data = utils.float_array(data[0])
File "/usr/lib/python2.6/dist-packages/Gnuplot/utils.py", line 33, in float_array
return numpy.asarray(m, numpy.float32)
File "/usr/lib/python2.6/dist-packages/numpy/core/numeric.py", line 230, in asarray
return array(a, dtype, copy=False, order=order)
ValueError: setting an array element with a sequence.
接着,我尝试把它转换成以下列表:
[['2013-01-15', 16.00], ['2013-01-16', 15.98], ['2013-01-17', 15.94]]
结果还是一样。
有没有人知道问题出在哪里?
谢谢。
1 个回答
2
我认为问题出在gnuplot-py中的这一行代码上,这是我从错误信息中提取出来的:
return numpy.asarray(m, numpy.float32)
发生的事情是,gnuplot-py试图把你的日期时间(或字符串)数据转换成一个 numpy.float32
对象。不过,如果你愿意花点时间去调整一下,可能可以让它正常工作。
经过检查,解决方案中的这一部分可能并不是必需的。 首先,你需要把 utils.py
中的那一行改成使用 numpy.float64
,而不是 numpy.float32
,然后重新安装 gnuplot-py
。这样我们就可以使用比较标准的时间戳格式。(另外,你也可以直接修改错误信息中提到的文件,这样可能就不需要重新安装了——错误信息里还给出了行号):
File "/usr/lib/python2.6/dist-packages/Gnuplot/utils.py", line 33, in float_array
return numpy.asarray(m, numpy.float32)
现在第33行变成了 numpy.asarray(m,numpy.float64)
,
这样我们就可以用浮点数来存储时间戳信息(我觉得 float32
的精度不够……)
def secs_since_epoch(date_time,epoch=datetime.datetime(1970,1,1,0,0,0)):
"""
compute seconds since a particular epoch. The default epoch is the unix
epoch -- e.g. Jan. 1 1970.
"""
dt = date_time - epoch #time elapsed since unix epoch
return dt.days*24*3600 + dt.seconds + dt.microseconds*1e-6 #converted to seconds
你可以使用这个函数将你的日期时间对象转换成简单的(双精度)浮点数。幸运的是,gnuplot也能读取这种格式的时间对象:
gp = Gnuplot.Gnuplot()
gp('set data style linespoints')
gp('set xdata time')
gp('set timefmt "%s"')
xmin = secs_since_epoch(datetime.datetime(2012,12,20,0,0))
xmax = secs_since_epoch(datetime.datetime(2012,2,12,0,0))
gp('set xrange [%s:%s]' % (xmin,xmax) )
gp.plot(data)
以下脚本对我来说运行得不错:
import datetime
import Gnuplot
data = [[datetime.datetime(2013, 1, 15, 17, 45), 16.00],
[datetime.datetime(2013, 1, 16, 17, 45), 15.98],
[datetime.datetime(2013, 1, 17, 17, 45), 15.94]]
def secs_since_epoch(date_time,epoch=datetime.datetime(1970,1,1,0,0,0)):
"""
compute seconds since a particular epoch. The default epoch is the unix
epoch -- e.g. Jan. 1 1970.
"""
dt = date_time - epoch #time elapsed since unix epoch
return dt.days*24*3600 + dt.seconds + dt.microseconds*1e-6 #converted to seconds
dt,vals = zip(*data)
data = zip(map(secs_since_epoch,dt),vals)
gp = Gnuplot.Gnuplot(debug=True)
gp('set style data linespoints')
gp('set xdata time')
gp('set timefmt "%s"')
xmin = secs_since_epoch(datetime.datetime(2012,12,20,0,0))
xmax = secs_since_epoch(datetime.datetime(2012,2,12,0,0))
#gp('set xrange [%s:%s]' % (xmin,xmax) )
d = Gnuplot.Data(data)
d.set_option(using="1:2")
gp.plot(d)
raw_input()