简体   繁体   English

如何使用matplotlib在同一张图上绘制具有不同采样率的两个时间序列

[英]how to plot two time series that have different sample rates on the same graph with matplotlib

I have two sets of data that I would like to plot on the same graph. 我想在同一张图中绘制两组数据。 Both sets of data have 200 seconds worth of data. 两组数据都有200秒的数据价值。 DatasetA (BLUE) is sampled at 25 Hz and DatasetB (Red) is sampled at 40Hz. 数据集A(蓝色)以25 Hz采样,数据集B(红色)以40Hz采样。 Hence DatasetA has 25*200 = 5000 (time,value) samples... and DatasetB has 40*200 = 8000 (time,value) samples. 因此,数据集A具有25 * 200 = 5000(时间,值)的样本...而数据集B具有40 * 200 = 8000(时间,值)的样本。

datasets with different sample rates 具有不同采样率的数据集

As you can see above, I have managed to plot these in matplotlib using the 'plot_date' function. 如您在上面看到的,我已经使用'plot_date'函数在matplotlib中绘制了这些图。 As far as I can tell, the 'plot' function will not work because the number of (x,y) pairs are different in each sample. 据我所知,“图”功能将不起作用,因为每个样本中(x,y)对的数量不同。 The issue I have is the format of the xaxis. 我遇到的问题是xaxis的格式。 I would like the time to be a duration in seconds, rather than an exact time of the format hh:mm:ss. 我希望时间以秒为单位,而不是格式为hh:mm:ss的确切时间。 Currently, the seconds value resets back to zero when it hits each minute (as seen in the zoomed out image below). 当前,秒数值在击中每分钟时重置为零(如下面的缩小图像所示)。

zoomed out full time scale 缩小全时刻度

How can I make the plot show the time increasing from 0-200 seconds rather than showing hours:min:sec ? 如何使图显示时间从0-200秒增加,而不是显示hours:min:sec?

Is there a matplotlib.dates.DateFormatter that can do this (I have tried, but can't figure it out...)? 是否有一个matplotlib.dates.DateFormatter可以做到这一点(我已经尝试过,但无法弄清楚……)? Or do I somehow need to manipulate the datetime x-axis values to be a duration, rather than an exact time? 还是我需要以某种方式将datetime x轴值操纵为持续时间,而不是精确的时间? (how to do this)? (这个怎么做)?

FYI: The code below is how I am converting the original csv list of float values (in seconds) into datetime objects, and again into matplotlib date-time objects -- to be used with the axes.plot_date() function. 仅供参考:下面的代码是我将原始csv浮点值列表(以秒为单位)转换为日期时间对象,然后再次转换为matplotlib日期时间对象的方式-与axes.plot_date()函数一起使用。

from matplotlib import dates        
import datetime 

## arbitrary start date... we're dealing with milliseconds here.. so only showing time on the graph.
base_datetime = datetime.datetime(2018,1,1)
csvDateTime = map(lambda x: base_datetime + datetime.timedelta(seconds=x), csvTime)
csvMatTime = map(lambda x: dates.date2num(x), csvDateTime)

Thanks for your help/suggestions! 感谢您的帮助/建议!

Well, thanks to ImportanceOfBeingErnst for pointing out that I was vastly over-complicating things... 好吧,感谢ImportanceOfBeingErnst指出我过于复杂了……

It turns out that I really only need the ax.plot(x,y) function rather than the ax.plot_date(mdatetime, y) function. 事实证明,我真的只需要ax.plot(x,y)函数,而不是ax.plot_date(mdatetime, y)函数。 Plot can actually plot varied lengths of data as long as each individual trace has the same number of x and y values. 只要每个单独的迹线具有相同数量的x和y值,绘图就可以绘制出不同长度的数据。 Since the data is all given in seconds I can easily plot using 0 as my "reference time". 由于所有数据都是以秒为单位给出的,因此我可以轻松地将0用作“参考时间”进行绘制。

For anyone else struggling with plotting duration rather than exact times, you can simply manipulate the "time" (x) data by using python's map() function, or better yet a list comprehension to "time shift" the data or convert to a single unit of time (eg simply turn minutes into seconds by dividing by 60). 对于任何其他想要绘制持续时间而不是精确时间的人,您可以使用python的map()函数简单地操作“时间”(x)数据,或者更好的是通过列表理解来“时移”数据或转换为单个数据时间单位(例如,将分钟除以60即可转换成秒)。

"Time Shifting" might look like: “时移”可能看起来像:

# build some sample 25 Hz time data
time = range(0,1000,1)
time = [x*.04 for x in time]
# "time shift it by 5 seconds, since this data is recorded 5 seconds after the other signal
time = [x+5 for x in time]

Here is my plotting code for any other matplotlib beginners like me :) (this will not run, since I have not converted my variables to generic data... but nevertheless it is a simple example of using matplotlib.) 这是我像其他任何matplotlib初学者的绘图代码:)(这不会运行,因为我没有将变量转换为通用数据...但是,这是使用matplotlib的简单示例。)

fig,ax = plt.subplots()
ax.grid()
ax.set_title(plotTitle)
ax.set_xlabel("time (s)")
ax.set_ylabel("value")

# begin looping over the different sets of data.
tup = 0
while (tup < len(alldata)):
    outTime = alldata[tup][1].get("time")
    # each signal is time shifted 5 seconds later.
    # in addition each signal has different sampling frequency, 
    # so len(outTime) is different for almost every signal.
    outTime = [x +(5*tup) for x in outTime]
    for key in alldata[tup][1]:
        if(key not in channelSelection):
            ## if we dont want to plot that data then skip it.
            continue
        else:
            data = alldata[tup][1].get(key)
            ## using list comprehension to scale y values.
            data = [100*x for x in data]
        ax.plot(outTime,data,linestyle='solid', linewidth='1', marker='')
    tup+=1
plt.show()     

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

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