我正在处理一项任务,我需要计算每天花费的时间,然后使用条形图来表示时间,所以对于这个任务,我使用python并且能够在每天花费时间并将其存储起来在列表" time_list"中,现在我不了解如何使用matplotlib函数绘制它。 问题是,此列表包含datetime.timedelta类值。 例如:
time_list
[datetime.timedelta(0, 23820), datetime.timedelta(0, 27480), datetime.timedelta(0, 28500), datetime.timedelta(0, 24180), datetime.timedelta(0, 27540), datetime.timedelta(0, 28920), datetime.timedelta(0, 28800), datetime.timedelta(0, 29100), datetime.timedelta(0, 29100), datetime.timedelta(0, 24480), datetime.timedelta(0, 27000)]
这些价值意义如下:
Total Time Spent on 2 is 6:37:00
Total Time Spent on 3 is 7:38:00
Total Time Spent on 4 is 7:55:00
Total Time Spent on 5 is 6:43:00
Total Time Spent on 8 is 7:39:00
Total Time Spent on 9 is 8:02:00
Total Time Spent on 10 is 8:00:00
Total Time Spent on 11 is 8:05:00
Total Time Spent on 12 is 8:05:00
Total Time Spent on 15 is 6:48:00
Total Time Spent on 16 is 7:30:00
有人可以帮我策划这个。 提前致谢
答案 0 :(得分:3)
我认为你不能在Matplotlib中直接绘制timedelta
,但由于你已经有秒数,你可以定义一个自定义刻度格式,将秒转换为小时和分钟。
from matplotlib.ticker import FuncFormatter
def format_func(x, pos):
hours = int(x//3600)
minutes = int((x%3600)//60)
seconds = int(x%60)
return "{:d}:{:02d}".format(hours, minutes)
# return "{:d}:{:02d}:{:02d}".format(hours, minutes, seconds)
formatter = FuncFormatter(format_func)
然后,您可以为y轴设置刻度格式化程序。
以下是使用bar
的示例。
labels = [2, 3, 4, 5, 8, 9, 10, 11, 12, 15, 16]
seconds = [i.seconds for i in time_list]
f = plt.figure()
ax = f.add_subplot(1,1,1)
ax.bar(labels, seconds)
ax.yaxis.set_major_formatter(formatter)
# this locates y-ticks at the hours
ax.yaxis.set_major_locator(matplotlib.ticker.MultipleLocator(base=3600))
# this ensures each bar has a 'date' label
ax.xaxis.set_major_locator(matplotlib.ticker.MultipleLocator(base=1))
答案 1 :(得分:2)
虽然matplotlib原则上可以处理日期时间对象,但条形图无法直接解释它们。因此,可以向timedeltas添加任意日期并使用matplotlib.dates.date2num()
转换为数字。然后使用DateFormatter
启用不错的刻度标记。
import numpy as np
import datetime
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
days = [2, 3, 4, 5, 8, 9, 10, 11, 12, 15, 16]
time_list = [datetime.timedelta(0, 23820), datetime.timedelta(0, 27480),
datetime.timedelta(0, 28500), datetime.timedelta(0, 24180),
datetime.timedelta(0, 27540), datetime.timedelta(0, 28920),
datetime.timedelta(0, 28800), datetime.timedelta(0, 29100),
datetime.timedelta(0, 29100), datetime.timedelta(0, 24480),
datetime.timedelta(0, 27000)]
# specify a date to use for the times
zero = datetime.datetime(2018,1,1)
time = [zero + t for t in time_list]
# convert datetimes to numbers
zero = mdates.date2num(zero)
time = [t-zero for t in mdates.date2num(time)]
f = plt.figure()
ax = f.add_subplot(1,1,1)
ax.bar(days, time, bottom=zero)
ax.yaxis_date()
ax.yaxis.set_major_formatter(mdates.DateFormatter("%H:%M"))
# add 10% margin on top (since ax.margins seems to not work here)
ylim = ax.get_ylim()
ax.set_ylim(None, ylim[1]+0.1*np.diff(ylim))
plt.show()
答案 2 :(得分:1)
当我想用等于y axis
类型的Timedelta64[ns]
绘制数据时,我遇到了类似的问题。我从以下博客中找到了解决此问题的最简单解决方案:solution。简而言之,只需将列的dtype
更改为.astype('timedelta64[m]')
。您只需更改方括号中的值,即可将其更改为小时,分钟或秒。它将y
列的dtype更改为float64
,然后您可以轻松绘制条形图或以正常单位而不是纳秒的方式绘制