2016-01-22 134 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