【问题标题】:Stacked histogram with datetime in matplotlibmatplotlib中带有日期时间的堆叠直方图
【发布时间】:2016-04-28 21:12:51
【问题描述】:

我正在尝试使用日期时间对象创建堆叠直方图,但出现以下错误:

 TypeError: unorderable types: datetime.datetime() < float()

当我将对象转换为时间戳或使用一个数据范围(无堆叠)时,代码确实有效。

import datetime
import matplotlib.pyplot as plt

data = [[datetime.datetime(2015, 12, 24, 21, 13, 45), datetime.datetime(2015, 12, 30, 23, 37, 8), datetime.datetime(2015, 12, 30, 19, 43, 18), datetime.datetime(2015, 12, 30, 16, 14, 12), datetime.datetime(2015, 12, 30, 11, 32, 8), datetime.datetime(2015, 12, 29, 6, 29, 25), datetime.datetime(2015, 12, 28, 22, 54, 49), datetime.datetime(2015, 12, 28, 18, 41, 50), datetime.datetime(2015, 12, 28, 14, 25, 42), datetime.datetime(2015, 12, 28, 3, 1, 34), datetime.datetime(2015, 12, 27, 21, 10, 20), datetime.datetime(2015, 12, 27, 11, 29, 38), datetime.datetime(2015, 12, 26, 20, 34, 14), datetime.datetime(2015, 12, 26, 16, 58, 47), datetime.datetime(2015, 12, 26, 10, 54, 40), datetime.datetime(2015, 12, 25, 18, 17, 42), datetime.datetime(2015, 12, 24, 15, 44, 58), datetime.datetime(2015, 12, 25, 17, 25, 9), datetime.datetime(2015, 12, 25, 12, 33, 7), datetime.datetime(2015, 12, 30, 19, 26, 15), datetime.datetime(2015, 12, 30, 12, 46, 13), datetime.datetime(2015, 12, 30, 3, 38, 24), datetime.datetime(2015, 12, 25, 21, 11, 59), datetime.datetime(2015, 12, 25, 13, 30, 34), datetime.datetime(2015, 12, 24, 14, 6, 20)], [datetime.datetime(2015, 12, 28, 20, 59, 53), datetime.datetime(2015, 12, 27, 14, 3, 41), datetime.datetime(2015, 12, 26, 9, 37, 17)], [datetime.datetime(2015, 12, 29, 17, 18, 32)], [datetime.datetime(2015, 12, 29, 23, 15, 24)]]

fig, histograms = plt.subplots(5, 1, sharex=True, squeeze=False)
h = histograms[1][0]
h.hist(data, stacked=True)

这是没有堆叠的代码:

import datetime
import matplotlib.pyplot as plt

data = [datetime.datetime(2015, 12, 24, 21, 13, 45), datetime.datetime(2015, 12, 30, 23, 37, 8), datetime.datetime(2015, 12, 30, 19, 43, 18), datetime.datetime(2015, 12, 30, 16, 14, 12), datetime.datetime(2015, 12, 30, 11, 32, 8), datetime.datetime(2015, 12, 29, 6, 29, 25), datetime.datetime(2015, 12, 28, 22, 54, 49), datetime.datetime(2015, 12, 28, 18, 41, 50), datetime.datetime(2015, 12, 28, 14, 25, 42), datetime.datetime(2015, 12, 28, 3, 1, 34), datetime.datetime(2015, 12, 27, 21, 10, 20), datetime.datetime(2015, 12, 27, 11, 29, 38), datetime.datetime(2015, 12, 26, 20, 34, 14), datetime.datetime(2015, 12, 26, 16, 58, 47), datetime.datetime(2015, 12, 26, 10, 54, 40), datetime.datetime(2015, 12, 25, 18, 17, 42), datetime.datetime(2015, 12, 24, 15, 44, 58), datetime.datetime(2015, 12, 25, 17, 25, 9), datetime.datetime(2015, 12, 25, 12, 33, 7), datetime.datetime(2015, 12, 30, 19, 26, 15), datetime.datetime(2015, 12, 30, 12, 46, 13), datetime.datetime(2015, 12, 30, 3, 38, 24), datetime.datetime(2015, 12, 25, 21, 11, 59), datetime.datetime(2015, 12, 25, 13, 30, 34), datetime.datetime(2015, 12, 24, 14, 6, 20), datetime.datetime(2015, 12, 28, 20, 59, 53), datetime.datetime(2015, 12, 27, 14, 3, 41), datetime.datetime(2015, 12, 26, 9, 37, 17), datetime.datetime(2015, 12, 29, 17, 18, 32), datetime.datetime(2015, 12, 29, 23, 15, 24)]

fig, histograms = plt.subplots(5, 1, sharex=True, squeeze=False)
h = histograms[1][0]
h.hist(data, stacked=True)

注意: 根据答案,这被认为是一个错误。对于未来的访问者,我已提交错误报告https://github.com/matplotlib/matplotlib/issues/5898,以防您想跟踪进度

【问题讨论】:

  • 我用您要求的示例更新了我的答案。在这里,我会选择 1 天的 bin 宽度,这使得 N=6。实际上我有更多的数据
  • 是的,它在 1.5.0 版中工作。是的,正如我发布的问题一样,它也可以使用时间戳(自 UNIX 纪元以来的秒数)

标签: python datetime python-3.x matplotlib


【解决方案1】:

这是一个错误,1.5.x 版本支持单系列datetime 类型数据的直方图。以前版本的 matplotlib 不会对日期时间数据进行直方图,无论是否堆叠,都会失败并出现类似的错误,即无法将日期时间与浮点数进行比较。

异常由this line of code 抛出。如您所见,仅当未指定 bin 边缘并试图找到时间序列中的最小值时才调用它(将其与 np.inf 进行比较并取其中的最小值)。您可以通过在调用中指定 bin 边缘来解决此问题,但这会导致进一步失败,因为在后台调用的 numpy histogram 函数会查找宽度小于零的 bin。

“幕后”当datetime.datetime 对象的单个列表传递给pyplot.hist() 函数时,数据实际上被转换为UNIX 纪元时间戳(您可以从x 轴的标签中猜到这一点)。当输入是datetime.datetime 对象的列表时,不会这样做。

在那个阶段,我认为我们必须将其称为错误,并且您必须使用 timestamp,正如您已经发现的那样 - 例如。 h.hist([[t.timestamp() for t in s] for s in data], stacked=True)。您仍然可以以日期格式给出 bin 标签,即使被直方图绘制的实际数据是时间戳,因此这对用户应该是透明的。

我会看看是否可以找到更好的解决方法/修复并可能在 matplotlib github 上提出问题。

有效的代码(matplotlib 1.5.1,Python 3),虽然有点乱

import datetime
import matplotlib.pyplot as plt

data = [[datetime.datetime(2015, 12, 24, 21, 13, 45), datetime.datetime(2015, 12, 30, 23, 37, 8), datetime.datetime(2015, 12, 30, 19, 43, 18), datetime.datetime(2015, 12, 30, 16, 14, 12), datetime.datetime(2015, 12, 30, 11, 32, 8), datetime.datetime(2015, 12, 29, 6, 29, 25), datetime.datetime(2015, 12, 28, 22, 54, 49), datetime.datetime(2015, 12, 28, 18, 41, 50), datetime.datetime(2015, 12, 28, 14, 25, 42), datetime.datetime(2015, 12, 28, 3, 1, 34), datetime.datetime(2015, 12, 27, 21, 10, 20), datetime.datetime(2015, 12, 27, 11, 29, 38), datetime.datetime(2015, 12, 26, 20, 34, 14), datetime.datetime(2015, 12, 26, 16, 58, 47), datetime.datetime(2015, 12, 26, 10, 54, 40), datetime.datetime(2015, 12, 25, 18, 17, 42), datetime.datetime(2015, 12, 24, 15, 44, 58), datetime.datetime(2015, 12, 25, 17, 25, 9), datetime.datetime(2015, 12, 25, 12, 33, 7), datetime.datetime(2015, 12, 30, 19, 26, 15), datetime.datetime(2015, 12, 30, 12, 46, 13), datetime.datetime(2015, 12, 30, 3, 38, 24), datetime.datetime(2015, 12, 25, 21, 11, 59), datetime.datetime(2015, 12, 25, 13, 30, 34), datetime.datetime(2015, 12, 24, 14, 6, 20)], [datetime.datetime(2015, 12, 28, 20, 59, 53), datetime.datetime(2015, 12, 27, 14, 3, 41), datetime.datetime(2015, 12, 26, 9, 37, 17)], [datetime.datetime(2015, 12, 29, 17, 18, 32)], [datetime.datetime(2015, 12, 29, 23, 15, 24)]]

fig, histograms = plt.subplots(5, 1, sharex=True, squeeze=False)
h = histograms[1][0]

h.hist([[t.timestamp() for t in l] for l in data], stacked=True)

locs, labels = plt.xticks()
plt.xticks(locs,[datetime.datetime.fromtimestamp(t) for t in locs], rotation='vertical')
plt.gcf().subplots_adjust(bottom=0.4)
fig.set_size_inches(4, 15)

plt.show()

生产

【讨论】:

    猜你喜欢
    • 2021-06-11
    • 2017-07-01
    • 2013-07-04
    • 2019-08-17
    • 2016-12-30
    • 1970-01-01
    • 2013-12-24
    • 2017-06-22
    • 2021-08-12
    相关资源
    最近更新 更多