在matplotlib中使用日期时间堆积直方图

时间:2016-01-22 10:00:04

标签: python datetime python-3.x matplotlib

我正在尝试使用datetime对象创建堆叠直方图,但是我收到以下错误:

 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 个答案:

答案 0 :(得分:3)

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

this line of code抛出了异常。正如您所看到的那样,只有在未指定bin边缘并且尝试在时间序列中找到最小值时才会调用它(将其与np.inf进行比较并取其最小值)。你可以通过在调用中指定bin边缘来解决这个问题,但是这会导致进一步的失败,因为在引擎盖下调用的numpy直方图函数会查找小于零的宽度区域。

&#34;引擎盖下&#34;当单个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()

可生产

Stacked bar with date labels