MATLAB Change numbers to date - matlab

I have time set up as serial dates. Each number corresponds to a day, in order, from 20100101 to 20130611. How do I convert the serial date to a date in the format month-year? I need this because I want to plot data and need the x axis to show the date.
Thanks!

The first step is to convert your date-format into one of the standard Matlab date formats. The best format to use for plots is the "serial date format". The numbers itself are a bit awkward, since they represent the "amount of time after 0/0/0000, in days", which is a huge number. Also, this date actually never existed, making it really weird when you want to work with dates that are BC.
However, the conversion is easy, since your format also counts the days, but you count after 31st of December, 2009. You can convert this using
numeric_date_vec = datenum(2009, 12, 31) + x;
You then plot your data using
plot(numeric_date_vec, y)
and you let Matlab add the date-ticks automatically by calling
datetick('mmm yyyy')
The problem is, the ticks do not update after zooming in. You can either call
datetick('mmm yyyy','keeplimits')
again, after each zooming or panning, or you download datetickzoom from the Matlab file exchange. It takes the same arguments as datetick, but it hooks into the zoom function and updates the ticks automatically.
Edit:
Sometimes, the dateticks are not spaced in any sensible way, then you can either try to zoom in and out a little until it snaps to something good, or you have to set the ticks manually:
% Set ticks to first day of the months in 2010
tick_locations = datenum(2012,[1:12],1);
% Set ticks on x-axis
set(gca, 'XTick', tick_locations)
% Call datetick again to get the right date labels, use option "keepticks"
datetick('mmm yyyy','keeplimits', 'keepticks')
You might have to modify the tick_locations = datenum(2012,[1:12],1) a bit to get the ticks that you want. For instance, you can use
tick_locations = datenum(2012,[1:2:25],1)
to get every second month between Jan 2012 and Jan 2013.

For day number n use
datestr(datenum(2009, 12, 31) + n, 'yyyy-mm')
for example
>> datestr(datenum(2009, 12, 31)+365, 'yyyy-mm')
ans =
2010-12
>> datestr(datenum(2009, 12, 31)+366, 'yyyy-mm')
ans =
2011-01

Related

Plot Two Regression Lines on Same Scatter Plot By Year: X-Axis Date MM/DD

I have a scatter plot of calls / time. My x variable is the date (Day/Month) and my Y variable is a number of calls on each date. I would like to plot two regression lines using PROC SGPLOT REG, one for 2019 and one for 2020. However, when I try to do this, all I get is a regular scatter plot with no regression lines. Here is my code:
proc sgplot data=intern.bothphase1;
reg x=date y=count / group=Year;
label count="Calls Per Day" year="Year";
Title "Comparison of EMS Calls per Day 1/1 - 3/31 in 2019 vs.
2020";
run;
The scatter plot comes up without issue (2019 and 2020 values in different colors) but I want to see how the trends differed between the two time periods, so I really want to get the regression lines on there. Can anyone help?
I imagine this has to do with the fact that I concatenated my day and month with a / so it is a character variable and so SAS cannot calculate the regression. I did this so I could use year as a class variable. I still have the original date variable in my table, is there a way I could get SAS to give me the month/day from that as a numeric variable?
Thanks!
EDIT: I used a date value in SAS and changed the format to mm/dd, but this doesn't help because the regression lines are just on either end of the graph rather than overlapping (picture attached). what I want is to have the regression lines overlap for the same time period 2019 vs. 2020 This is because SAS dates correspond to numbers from 1/1/1960. What I want is the mm/dd to correspond to numbers 1-365 so I get two overlapping regression lines to show how the trends changed from one year to the next. Anyone know how I can do this?
So two steps here: first, you need to generate a "day" value that's 1-365... so let's just subtract out 01JAN from the day value.
data have;
do date = '01JAN2019'd to '31DEC2020'd;
count = 25+2*rand('uniform');
year = year(date);
if month(date) le 3 then output;
end;
format date date9.;
run;
data adjusted;
set have;
date_fixed = date - intnx('year',date,0,'b') + 1; *current date minus jan 1 plus 1 (otherwise off by 1);
format date_fixed date5.; *this does not actually affect the graph axis, oddly;
run;
proc sgplot data=adjusted;
reg x=date_fixed y=count / group=Year;
xaxis valuesformat=date5.; *this seems to be needed for some reason;
label count="Calls Per Day" year="Year";
Title "Comparison of EMS Calls per Day 1/1 - 3/31 in 2019 vs.
2020";
run;
Then we add the xaxis line because for some reason it won't obey the DATE5. format (could also use MMDDYY5. as Reeza noted in comments, but we can force it to here.
Here is what I get. You can use other axis options to further limit things, so for example 01APR doesn't show up.
)

How to fill the last observations with retime in matlab?

I am interpolating variables from quarterly to monthly frequency in MATLAB. However, when I use retime it doesn't go as far as the end of the sample but it stops 2 months before.
Let me give you an example:
T = datetime(2002,01,01):calquarters:datetime(2019,12,01);
TT = timetable(T', randn(72,1))
x = retime(TT, 'monthly', 'spline') % interpolate
As you can see it gives me back 214 observations rather than 216, November and December 2019 are missing.
How can I fix it?
Thanks!
I don't have enough reputation to add a comment, but TT having 72 quarters instead of 73 means that you are actually storing dates from 1st January 2002 to 1st October 2019 - as the next quarter would start from 1st January 2020, which is then not included in your original array (you can check this by printing TT and checking if this date is included or not).
If this is the case, there is no way for retime to interpolate the missing months, as they aren't in the original matrix (that is, retime cannot interpolate from October to January, since there is no such thing in TT).
Replacing datetime(2019,12,01) with datetime(2020,01,01), as well as replacing randn(72,1) with randn(73,1), might solve your issue.

How to get monthly totals from linearly interpolated data

I am working with a data set of 10,000s of variables which have been repeatedly measured since the 1980s. The first meassurements for each variable are not on the same date and the variables are irregularly measured - sometimes measurements are only a month apart, in a small number of cases they are decades apart.
I want to get the change in each variable per month.
So far I have a cell of dates of measurements,and interpolated rates of change between measurements (each cell represents a single variable in either, and I've only posted the first 5 cells in each array)
DateNumss= {[736614;736641;736669] [736636;736666] 736672 [736631;736659;736685] 736686}
LinearInterpss={[17.7777777777778;20.7142857142857;0] [0.200000000000000;0] 0 [2.57142857142857;2.80769230769231;0]}
How do I get monthly sums of the interpolated change in variable?
i.e.
If the first measurement for a variable is made on the January 1st, and the linearly interpolated change between that an the next measurement is 1 per day; and the next measurement is on Febuary the 5th and the corresponding linearly interpolated change is 2; then January has a total change of 1*31 (31 days at 1) and febuary has a total change of 1*5+2*23 (5 days at 1, 23 days at 2).
You would need the points in the serial dates that correspond with the change of a month.
mat(:,1)=sort(repmat(1980:1989,[1,12]));
mat(:,2)=repmat(1:12,[1,size(mat,1)/12]);
mat(:,3)=1;
monthseps=datenum(mat);
This gives you a list of all 120 changes of months in the eighties.
Now you want, for each month, the change per day, and sum it. If you take the original data it is easier, since you can just interpolate each day's value using matlab. If you only have the "LinearInterpss" you need to map it on the days using interp1 with the method 'previous'.
for ct = 2:length(monthseps)
days = monthseps(ct-1):(monthseps(ct)-1); %days in the month
%now we need each day assigned a certain change. This value depends on your "LinearInterpss". interp1 with method 'previous' searches LineairInterpss for the last value.
vals = interp1(DateNumss,LinearInterpss,days,'previous');
sum(vals); %the sum over the change in each day is the total change in a month
end

MATLAB Display real-time dates on x-axis

I created a diagram presenting limb movement over the time (2.56 seconds). My diagram looks like in the top Picture 1.
My code to get the diagram was:
x=data(1000:1256,2)
Fs=100
Ts=1/Fs
L=length(x)
t = (0:L-1)*Ts;
figure
plot(t,x);
Now Im trying to change time units into real time data (day and time, when the measurements were recorded), I want to get something like in the Picture 2: mark x-axis with date and time. Ideally Id like to have 6 time marks.
Using:
datestr(data(1000),'dd-mm-yyyy HH:MM:SS AM')
I know the first time (row 1000th of my data) is 10-07-2010 11:31:50 PM and the last row (1256th) is 10-07-2010 11:43:42 PM. There was always 50 records recorded per 1 second, BUT the problem is, the measurements were not recorded constantly - I mean, sometimes there was no measurements for a few minutes (when there was no movement).
I ve been trying to use XTick etc but I dont know how to select the real-time data for my x-axis and how to label x-axis with the real time of measurements.
labels=datestr(data);
set(gca,'XTick',1:6; 'XTickLabel',labels);
Anybody could help me?
This should format the tickmarks
datetick('x', 'dd-mm-yyyy HH:MM:SS AM')
It might go after setting the tickmarks
set(gca,'XTick',[ ... ])
Where in the array you should put the datenum values of your times.
Consider this minimal example:
x = linspace(now-2, now, 30);
y = rand(30, 1);
plot(x, y)
datetick('x', 'dd-mmm HH:MM')

How do you use time as an axis in a Core Plot graph?

I have two arrays arr1 and arr2 containing datetime in dd/MM/yyyy HH:mm:ss and HH:mm:ss respectively.
For eg. arr1[0] contains 23/12/2011 09:15:30 while arr2[0] contains 09:15:30.
Note that arr1 will always contain today's date, which is exactly what I want for my iPad app which I'm preparing using Xcode 4.2.
I want to plot specific time (either from arr1 or from arr2 whichever is best suitable) on the X axis and corresponding float value contained in an array arr3 on Y-axis.
Now I'm stuck at plotting time on X axis as I can't pass time in dd/MM/yyyy HH:mm:ss or HH:mm:ss.
I googled about it and got the suggestion to use epoch but I'm unable to implement it for my app.
Other than using epoch, how can I pass a time value to Core Plot for the X axis?
Core Plot requires numeric plot data. You'll have to find a way to convert the dates to a number. One way is to convert each one to an epoch value as you mentioned. If the dates are not evenly spaced, that may be your only option.
If you know that the dates are spaced at regular intervals (e.g., hourly, daily, monthly, etc.) you could just figure an index that corresponds to each date. Make custom labels to display the dates and set the plot space range to cover the correct range of indices.