无法使用hist()函数在日期时间对象的直方图中对齐bin

emi*_*ily 5 python datetime matplotlib histogram bins

所以我试图绘制一些日期时间对象的直方图,但我永远不能让垃圾箱与酒吧对齐.我的代码如下:

我首先导入我的东西并声明开始,结束和一天的对象:

import datetime
import matplotlib.pyplot as plt

end = datetime.date(2017,5,14) 
start = datetime.date(2017,5,8) 
one_day = datetime.timedelta(days = 1)  
Run Code Online (Sandbox Code Playgroud)

然后我宣布一个任意的日期列表:

date_list = [datetime.date(2017,5,14), datetime.date(2017,5,14), 
datetime.date(2017,5,14), datetime.date(2017,5,9), datetime.date(2017,5,13), 
datetime.date(2017,5,12), datetime.date(2017,5,11), 
datetime.date(2017,5,11), datetime.date(2017,5,9)]
Run Code Online (Sandbox Code Playgroud)

然后我会经历开始和结束之间的天数范围(在本例中为一周),将每个日期添加到列表中:

week = [] 
for i in range((end-start).days+1):  
    week.append(start + (i)*one_day)
Run Code Online (Sandbox Code Playgroud)

原因是本周的某些日子没有出现在date_list中(我知道我可以在这种情况下跳过这个,但我希望它可以扩展到其他date_lists).

然后我用hist()绘图:

plt.hist(date_list, bins = len(week)+1)
plt.show()
Run Code Online (Sandbox Code Playgroud)

我尝试过各种各样的bin格式组合,各种+ 1和范围并且对齐,但日期从不坐在条形图中的一致位置.

Imp*_*est 6

如果只是设置 bin 的数量,则 bin 将平均分布在(数据的)第一个值和最后一个值之间。由于数据例如缺少该start值,bin 将小于一整天。

为了克服这一点,需要明确地将所需的 bin 设置为 的bins参数hist。不幸的是,这里不能直接使用日期时间列表,因此需要先将日期时间转换为数字。这可以使用 matplotlib 的matplotlib.dates.date2num方法来完成。

完整示例:

import datetime
import matplotlib.pyplot as plt
from matplotlib.dates import date2num

end = datetime.date(2017,5,14) 
start = datetime.date(2017,5,8) 
one_day = datetime.timedelta(days = 1)  

date_list = [datetime.date(2017,5,14), datetime.date(2017,5,14), 
datetime.date(2017,5,14), datetime.date(2017,5,9), datetime.date(2017,5,13), 
datetime.date(2017,5,12), datetime.date(2017,5,11), 
datetime.date(2017,5,11), datetime.date(2017,5,9)]

week = [] 
for i in range((end-start).days+1):  
    week.append(start + (i)*one_day)

numweek = date2num(week)

plt.hist(date_list, bins = numweek, ec="k")
plt.gcf().autofmt_xdate()
plt.show()
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明

请注意,datetime.date(2017,5,14)is 是(2017,5,13)和之间的 bin 的一部分(2017,5,14),因此您可能希望将结束日期设置为 datetime.date(2017,5,15)