Matlab: time series plot for 44100 hz data - matlab

I'm trying to plot a time series which has been collected at a rate of 44100 hz. I would like to have the time (in seconds) and possibly the date on the x-axis.
Say I have data for one minute, i.e. 2646001 data points and assume, for simplicity, all data points are ones:
y=repmat(1,2646001,1);
I created a vector of date numbers by converting the start and end date into serial date numbers and then create a vector from the first time number to the last time number with rate 44100 hz:
StartTimeNum = datenum(2013,11,12,23,00,0);
EndTimeNum = datenum(2013,11,12,23,01,0);
T = EndTimeNum-StartTimeNum;
TimeNum = StartTimeNum:(T/length(y)):EndTimeNum;
I then define the format I would like the date string to be in and convert the time number vector into time string.
FormatOut = 'dd/mm/yy, HH:MM:SS.FFF';
TimeStr= datestr(TimeNum, FormatOut);
but now TimeStr is a <2646001x22 char>, rather than a <2646001x1 char> which Matlab doesn't allow me to use as the input for the x-axis.
In another attempt I found the timeseries class (http://www.mathworks.co.uk/help/matlab/ref/timeseries.plot.html) which would be perfect, but because my data is in 44100 hz, I am not sure how to define the units (ts1.TimeInfo.Units), which are generally described as 'days', or 'hours' or 'seconds' but not in hz...
Is there any way around this?
Thanks

y=ones(2646001,1); % use ones(m,n) for more efficiency
StartTimeNum = datenum(2013,11,12,23,00,0);
EndTimeNum = datenum(2013,11,12,23,01,0);
T = EndTimeNum-StartTimeNum;
TimeNum = StartTimeNum:(T/(length(y)-1)):EndTimeNum; % length consistent
FormatOut = 'dd/mm/yy, HH:MM:SS.FFF';
figure,plot(TimeNum, y),datetick('x',FormatOut)

Plot your data vs. TimeNum directly, then use datetick to set the labels:
plot(TimeNum, y);
datetick('x', 'dd/mm/yy, HH:MM:SS.FFF');
Or try just datetick with no arguments. The default format might be better.

Related

Generate timestamp series in Matlab?

all
I wonder if there is a way to generate timestamp series in Matlab ?
I assume there will be a start time, a end time, and a frequency.
It is simple to generate normal series using 1:1:100 (1 to 100 by 1)
How I can use a similar way to generate a time stamp series?
For instance, I specify start time as 9am, up to 10am, I want to generate something like 9:00:00:000, 9:00:00:500, 9:00:01:000, ....
gaped by 500 millisecond
Or even better, include date as well.
Use datenum, the only problem you might have is that your colliding with a gap second/day or summer savings time if you're spanning a long time period (but I don't think that's implemented in datestr as you can read here).
Play around with datenum, now and datestr
starttime = datenum(2000, 1, 1, 9, 0, 0);
dt = 0.500/86400; % datenum is a serial time format with 1 = 1 day = 86400 sec
N = 5;
timevec = starttime + dt*(0:(N-1));
>> datestr(timevec, 'HH:MM:SS.FFF')
ans =
09:00:00.000
09:00:00.500
09:00:01.000
09:00:01.500
09:00:02.000
Starting from 2015a, you can use the milliseconds function to build a vector of timesteps between to time points:
start = datetime('2017/1/3 9:00:00:000','InputFormat','yyyy/MM/dd H:mm:ss:SSS');
step = milliseconds(500);
fin = datetime('2017/1/3 10:00:00:000','InputFormat','yyyy/MM/dd H:mm:ss:SSS');
time_vec = start:step:fin;
If you don't define the date explicitly it will choose the current date.
You can also have one structure for both the time and the data, you can use the timeseries class (using start from above):
data = rand(7201,1);
ts = timeseries(data,'Name','MyTs');
ts.TimeInfo.StartDate = start;
ts.TimeInfo.Units = 'milliseconds';
ts = setuniformtime(ts,'Interval',500);
This will create a time series object:
>> ts
timeseries
Common Properties:
Name: 'MyTs'
Time: [7201x1 double]
TimeInfo: [1x1 tsdata.timemetadata]
Data: [7201x1 double]
DataInfo: [1x1 tsdata.datametadata]
with the following time info:
>> ts.TimeInfo
tsdata.timemetadata
Package: tsdata
Uniform Time:
Length 7201
Increment 500 milliseconds
Time Range:
Start 03-Jan-2017 09:00:00
End 03-Jan-2017 10:00:00
Common Properties:
Units: 'milliseconds'
Format: ''
StartDate: '03-Jan-2017 09:00:00'
It depends on your needs, but you can consider using the combination of datetime() and one or many of days(), hours(), minutes(), seconds() etc. functions.
Lets write some code:
start=datetime(1985,07,13,9,0,0); % your start date
steps=seconds(0:0.5:100); % your vector with steps
timeseries=start+steps; % your time series
you can also set format for displaying data that meets your needs, to do so check datetime properties manual.

display clock time from decimal time in matlab

I have this code as part of my program to calculate the solar time. But my calculation using decimal time. And now, I need to display the result in clock time.
%To calculate solar time
stime = time + (((4*(Lloc-Lsm))+ Et)/60);
disp(['The true solar time is ' num2str(stime),'hr']); %To display the solar time
The answer goes like this:
The true solar time is 13.0501hr
How can I convert the time to clock time (12hr or 24 hr format). i.e the minute should multiply by 60 (0.0501*60min = 3.006) and the time should display as 13:03 or 1:03PM.
Appreciate your help. Thank you.
Regards, -researcher-
you can use the following
my_hour = floor(stime);
my_minute = round(mod(stime, 1) * 60);
disp(['The true solar time is ', num2str(my_hour), ':', num2str(my_minute)]);
Use datenum to convert to a serial date number and then datestr to build the string with appropriate format:
h = 13.0501; %// your computed decimal time
string = datestr(datenum([0 0 0 h 0 0]),14); %// or change "14" for other formats
The two formats you specify correspond to formats 13 through 16 in datestr (see link to the documentation above). For example, with format 14 the string is
>> disp(string)
1:03:00 PM

matlab - averaging for a given interval

I can calculate daily averages of a data set like so:
Jday = datenum('2010-11-01 00:00','yyyy-mm-dd HH:MM'):60/(60*24):...
datenum('2011-02-31 23:00','yyyy-mm-dd HH:MM');
Dat = rand(length(Jday),1);
DateV = datevec(Jday);
[~,~,b] = unique(DateV(:,1:3),'rows');
AvDat = abs(accumarray(b,Dat,[],#nanmean));
AvJday = abs(accumarray(b,Jday,[],#nanmean));
However, I would like to take an average of a data set given a number for the output resolution. For example, if I wrote
outRes = 86400; % in seconds
I would like to average the values so that the output resolution is equal to 86400 seconds, and if the outRes defined is shorter than the resolution of the data then no averaging will take place.
How can this be done?
You should be able to detect the resolution of the data by:
CurrentRes=mean(diff(Jday))*86400;
if (~all(diff(Jday)==CurrentRes))
error('Inequally distributed sampling times');
end
if (CurrentRes>outRes)
return;
Then the amount you need to downsample by is:
AveragingFactor=outRes/CurrentRes;
Then you can average by discarding some samples at the end (or start) and averaging:
Dat = reshape(Dat(1:end-mod(length(Dat),AveragingFactor),:),AveragingFactor,[]);
AvDat = mean(Dat,1)'; % Transpose to keep it as a column vector if necessary.

find indices in array, use indices as lookup, plot w/r/t time

I'm looking to find the n largest values in an array, then to use the indices of those found values as a look up into another array representing time. But I am wondering how I can plot this if i want time to display as a continuous variable. Do I need to zero out data? That wouldn't be preferable for my use case as I'm looking to save memory.
Let's say that I have array A, which is where I am looking for the max values. Then I have array T, which represents timestamps. I want my plot to display continuous time and plot() doesn't like arguments of differing size. How do most people deal with this?
Here's what I've got so far:
numtofind = 4;
A = m{:,10};
T = ((m{:,4} * 3600.0) + (m{:,5} * 60.0) + m{:,6});
[sorted, sortindex] = sort(A(:), 'descend');
maxvalues = sorted(1:numtofind);
maxindex = sortindex(1:numtofind);
corresponding_timestamps = T(maxindex);
%here i plot the max values against time/corresponding timestamps,
%but i want to place them in the right timestamp and display time as continuous
%rather than the filtered set:
plot(time_values, maxvalues);
When you say "time as continuous", do you mean you want time going from minimum to maximum? If so, you can just sort corresponding_timestamps and use that to reorder maxvalues. Even if you don't do that, you can still do plot(time_values, maxvalues, '.') to get a scatter plot which won't mess up your graph with lines.

analyzing time series in the frequency domain

I am attempting to analyse a time series with spectral analysis. I am trying to detect any periodicities in my data, which is composed of hourly measurements recorded for one week (24 * 7 = 168 measurements), I aim to show the diurnal component of the temperature variation. So far I have (for example):
clear all
StartDate = '2011-07-01 00:00';
EndDate = '2011-07-07 23:00';
DateTime=datestr(datenum(StartDate,'yyyy-mm-dd HH:MM'):60/(60*24):...
datenum(EndDate,'yyyy-mm-dd HH:MM'),...
'yyyy-mm-dd HH:MM');
DateTime=cellstr(DateTime);
DecDay = datenum(DateTime)-datenum(2011,0,0);
t = 0:25/length(DecDay):(25-0.1488);
x = sin(2*pi*50*t) + sin(2*pi*120*t);
y = x + 2*randn(size(t));
Y = fft(y,length(y));
Where would I go from here? any advice would be much appreciated.
Altered:
clear all
StartDate = '2011-07-01 00:00';
EndDate = '2011-07-07 23:00';
DateTime=datestr(datenum(StartDate,'yyyy-mm-dd HH:MM'):60/(60*24):...
datenum(EndDate,'yyyy-mm-dd HH:MM'),...
'yyyy-mm-dd HH:MM');
DateTime=cellstr(DateTime);
DecDay = datenum(DateTime)-datenum(2011,0,0);
x = cos((2*pi)/12*DecDay)+randn(size(DecDay));
% if you have the signal processing toolbox
[Pxx,F] = periodogram(x,rectwin(length(x)),length(x),1);
plot(F,10*log10(Pxx)); xlabel('Cycles/hour');
ylabel('dB/(Cycles/hour');
Can anyone suggest how I would convert the x axis to hours instead of cycles per hour? I have tried
plot(1./F,10*log10(Pxx)); xlabel('hours');
but this messes up the peridogram.
You may find it easier to start off with MATLAB's periodogram function, rather than trying to use the FFT directly. This takes care of windowing the data for you and various other implementation details.