简体   繁体   English

使用 matplotlib 和 python 绘制 datetime.timedelta

[英]Plot datetime.timedelta using matplotlib and python

I am working on a task, where I need to calculate time spent on each day and then represent that time using a bar plot, so for this task I used python and able to get time spent on each day, and stored it in a list "time_list", now I don't understand how to plot this using matplotlib function.我正在处理一项任务,我需要计算每天花费的时间,然后使用条形图表示该时间,因此对于此任务,我使用了 python 并能够获取每天花费的时间,并将其存储在列表中“time_list”,现在我不明白如何使用 matplotlib 函数绘制它。 The problem is that, this list contains datetime.timedelta class values.问题是,这个列表包含 datetime.timedelta 类值。 Example:示例:

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)]

And these values meaning is as follow:这些值的含义如下:

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

Can someone help me in plotting this.有人可以帮我策划这个。 Thanks in advance提前致谢

I don't think you can directly plot timedelta in Matplotlib, but since you already have the number of seconds, you can define a custom tick format that converts seconds to hours and minutes.我不认为您可以在 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)

Then, you can set the tick formatter for the y-axis.然后,您可以为 y 轴设置刻度格式器。

Here's an example using a bar .这是一个使用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))

示例条形图

While matplotlib can in principle handle datetime objects, the bar plot cannot interprete them directly.虽然 matplotlib 原则上可以处理日期时间对象,但条形图不能直接解释它们。 So one may add an arbitrary date to the timedeltas and convert to numbers using matplotlib.dates.date2num() .因此,可以向 timedeltas 添加任意日期并使用matplotlib.dates.date2num()转换为数字。 Then using a DateFormatter enables nice ticklabels.然后使用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()

在此处输入图片说明

I had similar problem when I wanted to plot the data with a y axis equal to Timedelta64[ns] type.当我想用等于Timedelta64[ns]类型的y axis绘制数据时,我遇到了类似的问题。 I found the easiest solution to handle this issue from this blog : solution .我从这个博客中找到了处理这个问题的最简单的解决方案: 解决方案 For short, just change the dtype of your column to .astype('timedelta64[m]') .对于短,只是改变了dtype色谱柱来.astype('timedelta64[m]') You can change to hour, minutes or seconds for your case just by changing the value in a square brackets.您只需更改方括号中的值,即可将您的情况更改为小时、分钟或秒。 It changes the dtype of your y column to float64 and then you can easily plot the bar graph or plot with normal units and not like nanoseconds它将y列的 dtype 更改为float64 ,然后您可以轻松地绘制条形图或使用正常单位而不是纳秒绘制

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM