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

Jen*_*ijn 5 python datetime matplotlib python-3.x

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

 TypeError: unorderable types: datetime.datetime() < float()
Run Code Online (Sandbox Code Playgroud)

当我将对象转换为时间戳或使用一个数据范围(无堆叠)时,代码可以正常工作.

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)
Run Code Online (Sandbox Code Playgroud)

这是没有堆叠的代码:

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)
Run Code Online (Sandbox Code Playgroud)

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

J R*_*ape 3

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

该异常是由这行代码引发的。正如您所看到的,仅当未指定 bin 边缘并且尝试找到时间序列中的最小值(将其与np.inf其中的最小值进行比较并取最小值)时才会调用该函数。您可以通过在调用中指定 bin 边缘来解决此问题,但这会导致进一步的失败,因为在幕后调用的 numpy 直方图函数会查找小于零宽度的 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()
Run Code Online (Sandbox Code Playgroud)

生产

带有日期标签的堆叠条