绘制python数据时间的累积图 [英] Plotting a cumulative graph of python datetimes

查看:397
本文介绍了绘制python数据时间的累积图的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

说我有一个datetimes的列表,我们知道每个datetime是事件发生的记录时间。



是否可能在matplotlib中绘制频率这个事件发生在一段时间后,在累积图中显示这些数据(使得每个点大于或等于之前所有的点),而不预处理此列表? (例如,将datetime对象直接传递给某些精美的matplotlib函数)



或者,我需要将这个数据表列表转换为字典项目列表,例如:



{year:1998,month:12,date:15,events:92}



然后从这个列表中生成一个图表?



对不起,如果这似乎是一个愚蠢的问题 - 我不是很熟悉matplotlib,并希望保存如果matplotlib已经可以处理datetime对象本身,那么我自己就做了这样的努力。

解决方案

这应该适合你:

 计数= arange(0,len(list_of_dates))
plot(list_of_dates,计数)

您当然可以给的任何常用选项调用图形来看待你想要的方式。 (我会指出,matplotlib非常擅长处理日期和时间。)



另一个选项将是 hist function - 它有一个选项'cumulative = True'可能是有用的。您可以创建一个累积直方图,显示在任何给定日期之前发生的事件数,如下所示:

  from pyplot import hist 
来自matplotlib.dates import date2num
hist(date2num(list_of_dates),cumulative = True)

但是这会产生一个条形图,这可能并不完全相同,在任何情况下,使水平轴上的日期标签正确显示可能需要一些Fudging。



编辑:我觉得你真正想要的是每个日期的一点(或酒吧),相应的y值是事件的数量已经发生了(包括?)那个日期。在这种情况下,我建议这样做:

  grouping_dates = [[d,len(list(g)) ] for d,g in itertools.groupby(list_of_dates,lambda k:k.date())] 
dates,counts = grouping_dates.transpose()
计数= counts.cumsum()
步骤(日期,计数)

groupby 来自 itertools 模块的函数将产生您要查找的数据类型:只有每个日期的单个实例,并附有一个列表(实际上是一个迭代器)具有该日期的 datetime 对象。如Jouni在评论中所建议的,步骤函数将给出一个图表,在每一天发生事件,因此我建议使用它代替 plot



(帽子提示给EOL提醒我关于 cumsum



如果您希望每天都有一分,无论当天是否发生任何事件,您需要更改上述代码有一点:

  from matplotlib.dates import drange,num2date 
date_dict = dict((d,len(list g)))for d,g in itertools.groupby(list_of_dates,lambda k:k.date()))
dates = num2date(drange(min(list_of_dates).date(),max(list_of_dates).date ()+ timedelta(1),timedelta(1)))
计数= asarray([date_dict.get(d.date(),0)for d in dates])。cumsum()
step (日期,计数)

我认为这不会对生成的情节产生影响通过步骤功能。


Say I have a list of datetimes, and we know each datetime to be the recorded time of an event happening.

Is it possible in matplotlib to graph the frequency of this event occuring over time, showing this data in a cumulative graph (so that each point is greater or equal to all of the points that went before it), without preprocessing this list? (e.g. passing datetime objects directly to some wonderful matplotlib function)

Or do I need to turn this list of datetimes into a list of dictionary items, such as:

{"year": 1998, "month": 12, "date": 15, "events": 92}

and then generate a graph from this list?

Sorry if this seems like a silly question - I'm not all too familiar with matplotlib, and would like to save myself the effort of doing this the latter way if matplotlib can already deal with datetime objects itself.

解决方案

This should work for you:

counts = arange(0, len(list_of_dates))
plot(list_of_dates, counts)

You can of course give any of the usual options to the plot call to make the graph look the way you want it. (I'll point out that matplotlib is very adept at handling dates and times.)

Another option would be the hist function - it has an option 'cumulative=True' that might be useful. You can create a cumulative histogram showing the number of events that have occurred as of any given date something like this:

from pyplot import hist
from matplotlib.dates import date2num
hist(date2num(list_of_dates), cumulative=True)

But this produces a bar chart, which might not be quite what you're looking for, and in any case making the date labels on the horizontal axis display properly will probably require some fudging.

EDIT: I'm getting the sense that what you really want is one point (or bar) per date, with the corresponding y-value being the number of events that have occurred up to (and including?) that date. In that case, I'd suggest doing something like this:

grouped_dates = [[d, len(list(g))] for d,g in itertools.groupby(list_of_dates, lambda k: k.date())]
dates, counts = grouped_dates.transpose()
counts = counts.cumsum()
step(dates, counts)

The groupby function from the itertools module will produce the kind of data you're looking for: only a single instance of each date, accompanied by a list (an iterator, actually) of all the datetime objects that have that date. As suggested by Jouni in the comments, the step function will give a graph that steps up at each day on which events occurred, so I'd suggest using that in place of plot.

(Hat tip to EOL for reminding me about cumsum)

If you want to have one point for every day, regardless of whether any events occurred on that day or not, you'll need to alter the above code a bit:

from matplotlib.dates import drange, num2date
date_dict = dict((d, len(list(g))) for d,g in itertools.groupby(list_of_dates, lambda k: k.date()))
dates = num2date(drange(min(list_of_dates).date(), max(list_of_dates).date() + timedelta(1), timedelta(1)))
counts = asarray([date_dict.get(d.date(), 0) for d in dates]).cumsum()
step(dates, counts)

I don't think it'll really make a difference for the plot produced by the step function though.

这篇关于绘制python数据时间的累积图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆