I have a bunch of time-indexed data, that I have to plot with MATLAB.
The current format of the time is as follows
23:55:42,-147928.686833054
23:55:43,-147928.404621219
23:55:44,-147928.219419702
23:55:45,-147928.395802099
23:55:46,-147928.492812417
23:55:47,-147928.413440339
23:55:48,-147928.386982979
I simply wish to plot the second column, the values, against the first column, the time.
I can of course take the first time point as 0, and next as 1, ..., and so on. However, I wish to stick with the original timing.
How may I deal with this type of time handily?
Convert your time values using datenum. Create an X-Y plot in the usual way. And ask for time-formatted labels with
datetick('x', 13)
For example:
plot(datenum(a(:,1)), a(:,2));
datetick('x', 13)
Try the property "XTickLabel" after plotting.
You can use it with a cell of strings of your data:
plot(second-column-values)
Times={'23:55:42','23:55:43',...}
set(gca,'XTickLabel',Times)
Related
I have a matrix that contains two columns of data. The first column has timestamps given in UNIX time and the second column has a corresponding data set.
I'm trying to plot this DATA with human-readable times on the bottom axis.
I've plotted the raw data, like so:
plot(DATA(:,1), DATA(:,2));
I know there is a timeseries() function in MATLAB, but I can't seem to get it working correctly. I should be able to plot the data, following the MATLAB documentation.
I've tried declaring the first column as a time series:
TS = timeseries(DATA(:,1));
Then I tried plotting the data, like so:
plot(TS, DATA(:,1));
Although this approach seems to make rational sense, I get the following error:
Error using plot
Data must be a single matrix Y or a list of pairs X,Y
I also tried to use the addsample() function to append the data to the time series and then plot it.
K = addsample(TS, DATA(:,2));
plot(K);
But doing this produced the following error:
A new sample must be specified either as a structure or by Property-Value pairs.
So how do I plot this time data correctly? Thank you!
I work quite often with posix time (i.e. unixtime) with other programs, but in matlab the easiest format to deal with time and date is the Matlab time serial number format.
To convert from Unix to Matlab I use a small conversion function extensively:
function matlabtime = unix2matlabtime(unixtime)
%// function matlabtime = unix2matlabtime(unixtime)
%//
%// input : ** unixtime ** : time vector in the UNIX time serial number
%// representation (seconds since 01-jan-1970)
%//
%// output : ** matlabtime ** : time vector in the Matlab time serial number
%// representation (days since 01-jan-0000)
pivot = datenum([1970 01 01 00 00 00]) ;
matlabtime = ( unixtime / 24 / 3600 ) + pivot ;
with this function saved somewhere on your path, you can plot your data like so:
%// Generate sample data
sampleunixtime = linspace( 1427205640 , 1427205900 ).' ; %'// ignore this comment
DATA = [sampleunixtime , sin(sampleunixtime./10) ] ;
%// get a time vector in Matlab time serial format, then plot
time = unix2matlabtime( DATA(:,1) ) ;
plot( time, DATA(:,2) )
%// Adjust X-Ticks in human readable format
set( gca , 'XTickLabel' , datestr( get(gca,'XTick'),'HH:MM:SS' ) )
To obtain:
look at the datenum and datestr documentation to see how to handle these. There are many predefined output format for the date/time or you can even build your own to refine to the precision you need (add millisecond, remove seconds, add the date etc ...).
Just be aware that the XTickLabel are now overriden, so they will not be updated automatically. So if you zoom or pan on your figure you'll have to re-run the last line of code to refresh the XTicks values.
(personally, I put this last line of code in a Matlab toolbar shortcut to have quick access to it at any time).
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 ....
I am currently trying to make 'nice looking' axis on my plot in Matlab. The values are samples where each is taken every 20ms. So on X axis I'd like to have time in ms. My general code for plotting data is very simple:
plot(1:size( data.matrix,1), data.matrix(:,1),'b');
So far I've been able to correctly display sample numbers on this axis:
Code:
set(gca,'XTick',(1:size(data.matrix,1))*20);
Result (a):
In the given example the number of samples equals 184, that makes:
time = 184 * 20ms = 3680ms
Because changing the XTick value didn't do much of a change, I've tested XTickLabel property:
Code:
set(gca,'XTickLabel',ceil(linspace(0,size(data.matrix,1)*20,10)));
Result (b):
Code:
set(gca,'XTickLabel',0:ceil((size(data.matrix,1)*20)/10):size(data.matrix,1)*20);
Result (c):
As you may see, the results aren't the worst one. But this is not what I am trying to achieve. My goal is to have values like this:
So it simply first plot's (result a) X axis multiplied by 20.
Can someone please tell me how to achieve this?
when you use :
plot(1:size( data.matrix,1), data.matrix(:,1),'b');
The first parameter 1:size( data.matrix,1) create a vector of consecutive integers representing the indices of your data points. Two things are wrong with that:
1) You do not need to specify it. Matlab plot function called with only the Y data will create this vector automatically and use it to plot the data.
2) These indices represent the position of your data in an array, they have no physical meaning (like "time" for your case).
The solution is to create a proper 'time' vector and send it as the first parameter to the plot function. This way Matlab will take care of the tick management and you don't have to temper with the manual xtick settings.
Look at the two ways of doing it in the example below and everything will be clear:
%// build a simple index "X" vector (as you were doing)
x_index = 1:size(data.matrix,1) ;
%// build a properly scaled time vector
timeInterval = 20 ; % in milliseconds
x_time = ( 0:size(data.matrix,1)-1 ) * timeInterval ;
plot( x_index , data.matrix(:,1) ) %// this will do like in your example
plot( x_time , data.matrix(:,1) ) %// this will do what you want
Can you not just do?
set(gca,'XTickLabel',(1:size(data.matrix,1))*20*20);
I have a 356*2 array lets call him tmp
When the (:,1) is in milisecs
Now i am looking to make a plot of X over y when i want the X be showed in HH:MM:SS.FFF secs
I have converted the secs to that format by
datestr(tmp(:,1)*0.001/24/3600,'HH:MM:SS.FFF')
But this is a string, how can i use it in my plot function
You can apply what are called date format strings to the axes of plots with built-in function datetick. For example, with your first column being time, you could call
plot(tmp(:, 1), tmp(:, 2))
to plot the data. Then call:
datetick('x', 'HH:MM:SS.FFF')
to format the values assigned to ticks on the x-axis based on the second input argument. NOTE that, in order to perform this conversion, the function assumes that the time data is in units of DAYS, so if your data is in milliseconds, you should divide your time data by (24*60*60*1000). Note also that when you zoom on this graph, the new labels will not be re-written at each scale as numeric ones would have been. To get around this, I thoroughly recommend datetickzoom from the MATLAB file exchange.
Use your original value of tmp(:,1) for the plot function and then use your datestr(tmp(:,1)*0.001/24/3600,'HH:MM:SS.FFF') as the label?
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.