如何获取matplotlib的date2num值

时间:2017-08-07 10:57:07

标签: python date datetime numpy matplotlib

我想找到一条直线的y截距。为此,我试图使用numpy的polyfit(),并且它不会将参数作为datetime,因此我将datetime转换为matplotlib的date2num,下次我尝试使用time.mktime(datetime.timetuple())转换相同的日期以获得matplotlib的相同结果date2num制作:

x1 = 2015-07-20 00:00:00
x2 = 2015-07-31 00:00:00
idx = [x1, x2]
y1 = 132.97
y2 = 122.642

# to vary the position of y-intercept i used foo
bar =  2015-07-31 00:00:00
foo = matplotlib.dates.date2num(bar) # returns = 735810.0

x = matplotlib.dates.date2num(idx)
y = [y1, y2]

x[0]
>>> 735799.0
x[1]
>>> 735810.0

coefficients = np.polyfit(x, y, 1)
polynomial = np.poly1d(coefficients)
x_axis = np.linspace(x[0], foo + 1, 3)  # linspace(start, end, num)
y_axis = polynomial(x_axis)
>>>[ 132.97        127.33654545  121.70309091] # y_axis output
y-intecept = y_axis[2]
print("y-intercept = ', y-intercept)
>>>121.703090909

当我尝试使用x1, x2而不是time.mktime(datetime.timetuple())转换matplotlib.dates.date2num(idx)时,我会得到不同的结果。

dx1 = time.mktime(x1.timetuple())
dx2 = time.mktime(x2.timetuple())
x = [dx1, dx2]
...
...
...
print("y-intercept = ', y-intercept)
>>> 122.641989133

如何在不使用matplotlib库的情况下获取matplotlib的date2num等结果,以便我可以在使用121.703090909期间获得生成的结果date2num

1 个答案:

答案 0 :(得分:0)

您可以通过复制matplotlib.dates source中的代码来重现matplotlib.dates.date2num的结果:

import datetime
import numpy as np

class _UTC(datetime.tzinfo):
    def utcoffset(self, dt):
        return datetime.timedelta(0)
    def tzname(self, dt):
        return str("UTC")
    def dst(self, dt):
        return datetime.timedelta(0)
UTC = _UTC()

def date2num(dt):
    tzi = getattr(dt, 'tzinfo', None)
    if tzi is not None:
        dt = dt.astimezone(UTC)
        tzi = UTC
    base = float(dt.toordinal())
    cdate = getattr(dt, 'date', lambda: None)()
    if cdate is not None:
        midnight_time = datetime.time(0, tzinfo=tzi)
        rdt = datetime.datetime.combine(cdate, midnight_time)
        base += (dt - rdt).total_seconds() / (60*60*24.)
    return base

x1 = datetime.datetime(2015,07,20)   # Datetime object without hours, minutes, seconds
x2 = datetime.datetime(2015,07,31,4,50) # Datetime object with hours, minutes

print x1.toordinal() # 735799 
print x2.toordinal() # 735810  hours, minutes, seconds get truncated

print date2num(x1) # 735799.0
print date2num(x2) # 735810.201389

import matplotlib.dates
print matplotlib.dates.date2num(x1) # 735799.0
print matplotlib.dates.date2num(x2) # 735810.201389

请注意,如果您只使用没有时间的日期,则转换就像

一样简单

x1.toordinal()