【问题标题】:how to obtain values as that of matplotlib's date2num如何获取 matplotlib 的 date2num 的值
【发布时间】:2018-01-14 15:52:02
【问题描述】:

我想找到一条直线的 y 截距。为此,我尝试使用 numpy 的 polyfit(),它不接受参数作为日期时间,因此我将 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

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

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

如何在不使用 matplotlib 库的情况下获得 matplotlib 的 date2num 之类的结果,以便我可以得到使用 date2num 时产生的结果 121.703090909

【问题讨论】:

  • x1 = 2015-07-20 00:00:00+00:00 是无效的语法。你是如何定义x1的?
  • 实际上该日期是从 datetime() 返回的,我将输出粘贴到此处以简化操作。
  • 不要这样简化事情。需要minimal reproducible example 来重现该问题。
  • 现在应该可以了,你现在可以检查一下吗?
  • x1 = 2015-07-20 00:00:00 仍然是无效的语法。需要检查您的代码是否正常工作的是您,而不是我。

标签: python date datetime numpy matplotlib


【解决方案1】:

您可以通过从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()

【讨论】:

    猜你喜欢
    • 2012-10-26
    • 1970-01-01
    • 2019-05-04
    • 1970-01-01
    • 1970-01-01
    • 2019-04-08
    • 1970-01-01
    • 2012-04-22
    • 2021-09-14
    相关资源
    最近更新 更多