2016-01-22 87 views
4

我试图创建一个datetime对象堆叠柱状图,但我得到了以下错误日期时间:叠加柱状图与matplotlib

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以防你想跟踪进度

+0

我我的答案更新了你要的例子。在这里,我会为1天的箱宽度,这使得N = 6。实际上,我有更多的数据 –

+0

是的,它在1.5.0版本中工作。是的,正如有问题,我发布它也使用时间戳(自UNIX时代以来的秒) –

回答

3

这是一个错误,版本1.5.x支持单个系列的datetime类型数据的直方图。以前版本的matplotlib不会对日期时间数据进行直方图叠加,也不会出现类似的错误,表明日期时间无法与浮点数进行比较。

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

当一个单一的datetime.datetime对象列表被传递给pyplot.hist()函数时,数据实际上被转换为UNIX纪元时间戳(你可以从x轴的标签中猜出这个)。当输入是对象列表datetime.datetime的列表时,不会执行此操作。

在那个阶段,我认为我们必须把它称为一个错误,你必须使用timestamp,就像你已经发现的那样 - 例如, h.hist([[t.timestamp() for t in s] for s in data], stacked=True)。即使直方图的实际数据是时间戳,您仍然可以以日期格式提供箱标签,因此这对用户应该是透明的。

我会看看我能否找到更好的解决方法/修复,并可能在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