LGTrader
LGTrader

Reputation: 2429

Select portion of timeseries

In the code below I create a simple data series, a time vector, and then a timeseries. I have no problem plotting both of them. (It's not important that they are on the same plot.) What I haven't been able to figure out is how to subset a portion of a timeseries as shown by the last command that fails with the error:

>> timeseriesTest
Error using timeseries/plot (line 27)
The plot method can only be used for a single timeseries object

Error in timeseriesTest (line 14)
plot(ts(25:end));

>> 

How do I extract the last 25 (in this case) values in the time series? IMPORTANT: While not true in the code below my timeseries have daily or weekly time stamps and I do need to preserve that. I.e.:

NewData = ts.data 

...isn't a good answer unless it's the only way to get a new extracted timeseries.

t=[1:50];
d=sin(2*pi*t/20);

ts = timeseries(2*d, t);

%plot data and timeseries
plot(d);
hold on;
plot(ts);

figure();
plot(d(25:end));
hold on;
plot(ts(25:end));

Upvotes: 3

Views: 5868

Answers (1)

rayryeng
rayryeng

Reputation: 104565

If you look at the properties of a TimeSeries object, when you run your code before you try and plot, this is what we see:

>> ts

  timeseries

  Common Properties:
            Name: 'unnamed'
            Time: [50x1 double]
        TimeInfo: [1x1 tsdata.timemetadata]
            Data: [1x1x50 double]
        DataInfo: [1x1 tsdata.datametadata]

You see that there is a Data field in your time series object, as well as a Time field that represents the time value at each point instance. If you want to individually access the fields, and plot the last 25 elements, do something like this:

plot(ts.Time(end-24:end), squeeze(ts.Data(end-24:end)));

ts is your TimeSeries object, and if you want to access fields within this said object, use the dot operator (.... and you've already figured that out). Once you use the dot operator, you simply access the field you want by using its appropriate name. Therefore, if you want the time values, use Time and if you want the data, use Data. Now, what may seem strange is that I used squeeze. squeeze removes singleton dimensions. If you can see, Data is a 1 x 1 x 50 array, when it should really be just a 50 x 1 array. The purpose of squeeze is to remove redundant dimensions to get our actual data.

Note that this only seems to happen if you only have one signal within your time series. Should we have multiple signals... say, if we wanted three signals of length 50, we would create a 50 x 3 matrix where each column denotes a single signal. It would look something like this:

>> t = 1:50;
>> A = rand(50,3);
>> ts = timeseries(A,t)

  timeseries

  Common Properties:
            Name: 'unnamed'
            Time: [50x1 double]
        TimeInfo: [1x1 tsdata.timemetadata]
            Data: [50x3 double]
        DataInfo: [1x1 tsdata.datametadata]

rand generates a random matrix or vector of values of any size you want in the range of [0-1]. You'll see that our signal is now 50 x 3. If you want to plot this, plot recognizes multiple signals per time frame.... so you can just do this:

plot(ts.Time, ts.Data);

This should generate a plot of three traces, each delineated by a different colour and within the same time frame specified by ts.Time.

Similarly, if you want to plot the last 25 points for each signal, simply do:

plot(ts.Time(end-24:end), ts.Data(end-24:end,:));

This code will access the last 25 rows of every column (i.e. every signal) in your Data and plot them all.

Upvotes: 7

Related Questions