Converting from datenum back to actual time - matlab

Ok, so I've been messing with what should be a simple problem. I'm trying to plot an numerical array (double) vs. the associated time stamp (cell) with the format of the DD-MM-YY HH:MM:SS (for example: 13-Mar-15 07:23:10).
I'm able to plot a single set using datetime(time stamp). Due to the data set it outputs the nice HH:MM on the x-axis. Very nice.
Now in order to plot 2 sets of values on the same graph, I've found that Matlab doesn't like to use the date_time twice for the x-axis, so then I go to the infamous datenum function, which is able to plot both on the same graph. However, it's in the serial value of time and it jacks with my plot sizing (i.e. the x-axis doesn't autosize).
With what should be a simple problem has actually caused me days scouring the internet trying to reconvert it back to my beloved HH:MM after converting the "time stamp" into the serial time.
I don't think that a code sample or data set should be necessary for example purposes. (but can provide if needed)
I've tried to use the datetick function, but can't get seem to get it working.

The trick with datenum and datetick is to set limits and tick positions before you call datetick, then make sure it doesn't redo them.
So, after plotting your two sets of data against the datenums it would go something like:
step = 1/24; % for hourly - adjust to preference
ticks = datenum('mystarttime'):step:datenum('myendtime')
set(gca,'XTick',ticks)
datetick('x','HH:MM','keepticks','keeplimits')

I work a lot with time series and most often I have to plot my data versus time/date.
Since Matlab never gave me a definitively convenient solution, for many years now I work this way:
I defined once and for all a Matlab shortcut (in the matlab shortcut toolbar):
containing the following code:
xticktemp = get(gca,'Xtick') ;
ticklabel = {datestr(xticktemp(1)) datestr(xticktemp(2:end),15) } ;
set(gca,'Xticklabel',ticklabel)
clear xticktemp ticklabel
I convert all my times with datenum and use this format for working (or posix time when more convenient, but it's another story), calculating and plotting. When I need to now exactly the time of an event in a human readable format, I press the shortcut and I obtain something like:
Of course there are 2 major limitations with this method:
This does not control the steps of the ticks (it just replicate what Matlab initially set)
You have to re-click your shortcut to refresh the tick labels everytime you zoom or pan the figure
For these reasons, when I need to finalize figure for presentation to others I won't use this trick and define my ticks exactly like I want them, but when you are simply working away, this shortcut has saved me hours (may be even days?) of fiddling around over the last 10 years ....

Related

Time series visualization with status update for multiple attributes

Below is the sample data. I Need to plot a chart to visualize status changes for multiple attributes over a period of time. Below are the additional points the visualization should handle. I am not looking for any specific charting solution to implement the visualization but rather get an idea of how this can be handled.
In the below data, there are three attributes(r1,r2,r3), but I could have up to 30.
For each attribute, the status can be Pass/Fail/Error for a given month (period).
There could be as many as 100 months of data to plot.
Request,Date,Status
r1,Jan, Pass
r2,Jan, Pass
r3,Jan, Fail
r1,Feb, Pass
r2,Feb, Fail
r3,Feb, Pass
r1,Mar, Pass
r2,Mar, Error
r3,Mar, Pass
r1,Apr, Pass
r2,Apr, Error
r3,Apr, Fail
r1,r2,r3 are student results each month.
You could use a line/bar plot :
code Pass/Fail/Error with 0,1,2 and plot it on y axis,
on x axis put R1/R2/R3 stacked with date, even if you have 100 months
you have to put a switch where you can choose the month
By the way your question is too vague...what are R1,R2,R3? it seems that is something that must be put in production

How do I format the output of my MATLAB command window?

Currently looking at this API page, I have tried inputting format loose and format compact, but to no avail. What I need to do is change the way this number is displayed on the command window:
I obtain the value by rounding it to the three most significant figures in the function which I call from my main function.
stat = round(mean(v_stat),3,'significant');
I display the values through this statement:
fprintf('Ratio of Compression for Blind Deconvolution: %d \n',stat1);
I need to know how to display this value as as it's proper state instead of being multiplied by e raised to power of something.
You need to change your format statement, e.g. (a float with 3 decimals).
fprintf('Ratio of Compression for Blind Deconvolution: %.3f \n',stat1);
see the matlab help for fprintf to understand more on the format api.
Note: the %d your using is for integers

Set exact time limits in Matlab plot

When facing data in the time domain i seem to run into problems setting the exact limits on the x-axis with matlab.
Thus i plot my data and give the xlim in matlab time and set the limits:
minTT = datenum(2008,10,31,17,12,00);
maxTT = datenum(2008,10,31,17,19,00);
xlim = ([minTT maxTT]);
Then i use the date tick option to convert the matlab timing to "real clock time".
datetick('x',13,'keepticks');
The 'keep ticks' option is still better than none and i tried with both.
But what i get out is a plot that is going from: 17:12:28 to 17:17:58.
I have tried editing the ticks on my own as suggested from another post at StackOverflow like this:
ticks = get(gca, 'xtick')
newTicks = linspace(ticks(1), ticks(end), 8);
set(gca,'Xtick', newTicks)
but even that doesn't work out and gives me limits from 17:12:28 to 17:17:31.
Is there any way to really force matlab to use specific times on the axis whether or not the data doesn't exactly start there?
You can use the 'keeplimits' flag to datetick() - it does just what it says, much like 'keepticks'

Time from sun's position and observer's location

I have satellite imagery with the latitude, longitude, and position of the sun (azimuth, zenith, and elevation), but no time-stamp.
Short of using an astronomy almanac, is there a way to calculate the time from the sun's position and image location?
I've seen Matlab scripts and ArcGIS tools that do the reverse of this, i.e. they calculate the sun's position based on the lat, lon, and time of the observer, but I'm missing the "time" variable in this case and would like to find it for all of the images.
Here's one (slightly rough) method, as the position calculators I've seen don't seem particularly easy to reverse-engineer for "time given a known date".
I took an existing sun position calculator, Sun Position from the file exchange. I then wrote two wrapper functions to this function to output info in a slightly more useful format for searching:
sun_hour → calculates hourly (zero minute) positions across a given date.
sun_min → given a date and hour, calculates minutely positions one hour either side of thate date/hour.
Since the original function is quick, both of these take fractions of a second even on my not particularly good computer.
Then, I wrote a quick time location function along the following lines, using measured azimuth alone (along with time/location inputs giving the date and position in the formats required by sun_position).
time.min = 0;
% find list of azimuths, find closest match
[azlist, zlist, hours] = sun_hour(time, location);
n = find(abs(azlist-azimuth)==min(abs(azlist-azimuth)));
time.hour = hours(n);
% ditto, but around the time found at previous step
[azlist, zlist, hours, minutes] = sun_min(time, location);
n = find(abs(azlist-azimuth)==min(abs(azlist-azimuth)));
% output time
time.hour = hours(n);
time.min = minutes(n);
I haven't thoroughly tested it but it seems to work fine for a rough estimate (of course, assuming the accuracy of the original position calculator is good). I'm assuming that you don't need any more accuracy than minutely (unless you're managing to measure the position very accurately). You will need to be careful about how whichever calculator you end up using handles time-zones, whether the output is local time or not, etc.
Since you know the day, in a loop you could make a guess at the time, get the sun position, use the result to automatically make a better guess until you get close enough. You could do this as a binary search.

Plotting data on time (date) axis

I have data like this:
22.10.1980. 100
25.10.1980. 120
26.10.1980. 12
(only much more of it, and for each date, several independent measurements on the right).
Now, this is probably trivial, but I've never done anything like it in MATLAB, and am having problems finding similar examples online. I need to plot the data on a time/showing dates axis (x axis), with all dates inside (so, 23. and 24. as well ... for which I don't have measurements).
How can I get dates to show up on a plot axis?
It seems like it might be the best to use datetick.
Usage: datetick('x') or datetick('x', dateformat) with the available formats as explained in the documentation.
Assuming your data file has the format given above, you could use textscan to read the data:
fid = fopen('data.txt','rt');
C = textscan(fid,'%s %s %s %d','Delimiter','.','CollectOutput',1);
fclose(fid);
The first cell of C will contain an N-by-3 cell array of strings (the parts of the date) and the second cell of C will contain an N-by-1 vector of the data measurements. You can create a date number for each measurement by first concatenating the 3 smaller strings into one date string and then using the datenum function:
t = datenum(strcat(C{1}(:,3),'-',C{1}(:,2),'-',C{1}(:,1)));
data = C{2};
Once you have a vector of date numbers t to go with your vector of measurements data, you can then plot them:
plot(t,data,'*'); %# Plot the points as asterisks
Now, you can change the x-axis labels to show the actual dates. One option is to use the function datetick, an easy and elegant solution given in steven's answer. Another option is to use the function datestr to create the labels yourself, then modify the XTick and XTickLabel properties of the current axes:
xpts = min(t):max(t); %# Make a full vector, filling in missing dates
set(gca,'XTick',xpts,'XTickLabel',datestr(xpts)); %# Set axes properties
NOTE: Whichever option you choose for changing the x-axis labels to date strings, you may run into trouble with the labels overlapping each other if the tick marks are too close together. You could fix this by reducing or repositioning the tick marks along the x-axis (by changing the XTick property) or by adjusting the axes FontSize property. If you wanted to rotate the labels to make them fit, you would have to erase the labels and create new rotated text objects for them. The following submission on The MathWorks File Exchange does just that:
Rotate Tick Label by Andrew Bliss
With datenum you can convert any string date into numerical format based on the date format symbols (see help datestr).
For example all this leads to the same numerical date representation:
datenum('15/05/2009 21:22','dd/mm/yyyy HH:MM');
datenum('15.05.2009 21:22','dd.mm.yyyy HH:MM');
datenum('21-22 15.05.2009','HH-MM dd.mm.yyyy');
datenum('21-22 05/15.2009','HH-MM mm/dd.yyyy');
...
The nice thing is that you can pass cell array (output from textscan) or char array directly to datenum and it will output numeric date array.
Datetick is a good option, as well as datetick2, which can be found here: MATLAB Central
Datetick2 allows panning and zooming, with adjustments to the time labels, depending on how far you're zoomed in.
I'm not sure about the dd.mm.yyyy format - you could use regexp or strrep to change the decimals to dashes if neccessary.
You can use datenum to convert the dates to a numbers, and plot the data as usual. lets say you put your dates vector in the variable called x.
Now, you can use
set(gca, 'xtick',x(1:10:end));
set(gca, 'xticklabel',datestr(x(1:10:end));
to set the ticks on the x axis.