matlab exporting data - matlab

I have a daq card from which data is continuosly acquired every 100 ms. Now I want to create a txt file which contains all the data. This txt file should also have a time
stamp and should have 5 column headers - zeit , channel1, channel2.... channel4.
This is the code I could write but I am confused how to print the data after the headers.
Also after every 100 ms secs new data comes in and this has to be appended to the end of the file .The time stamp is in a specific format because later I need to search for a number.
% Time stamp
A = datestr(now, 'mmmm dd, yyyy HH:MM:SS.FFF ')
format short g
datevec(A)
fid = fopen('acq.txt','w');
fprintf(fid,'%s\t',A)
A = 'Zeit';
dataName = 'channel';
fid = fopen('acq.txt','w');
fprintf(fid,'%s\t',A)
%# loop to write the rest of the header
x=5
for iModel = 1:x
fprintf(fid,'%s_%i\t',dataName,iModel);
end
data = rand( 10,10);
fprintf( 'acq.txt' , '%i' ,data);

If you dont close the file, there is no reason to open it twice. Two consecutive fprintfs would get you started after the first fopen:
fprintf(fid,'%s\t',datestr(now, 'mmmm dd, yyyy HH:MM:SS.FFF '))
fprintf(fid,'%s\t%s1\t%s2\t%s3\t%s4\t','Zeit',dataName,dataName,dataName,dataName)
to set up the headers. At this point remember to use fclose(fid). You can now loop through each time your data is read, and open the file for append fida = fopen('acq.txt','a'); followed by formatted data output:
fprintf(fida,'%f %f %f %f %f %f %f %f %f %f\n',data')
For some reason matlab displays the data in the first row first, so transposing it puts it in the same shape as the data as represented in matlab. Remember to close these files or you might run into errors.

Related

Plot in MATLAB using data from a txt file

I need to read data from a file and plot a graph with its data. The problem is:
(1) I can't change the format of data in the file
(2) The format contains information and characters that I don't know how to deal with.
Here is a part of the data file, it's in a txt format:
Estation;Date;Time;Temp1;Temp2;Pressure;
83743;01/01/2016;0000;31.9;25.3;1005.1;
83743;01/01/2016;1200;31.3;26.7;1005.7;
83743;01/01/2016;1800;33.1;25.4;1004.3;
83743;02/01/2016;0000;26.1;24.2;1008.6;
What I'm trying to do is to plot the Date and Time against Temp1 and Temp2, not worrying about Pressure. The first column can be neglected as well. How can I extract the Date, Time and Temps into and matrix so I can plot them? All I did so far was this:
fileID = fopen('teste.txt','r');
[A] = fscanf(fileID, ['%d' ';']);
fclose(fileID);
disp(A);
Which just reads the first value, 83743.
To build on m7913d's answer:
fileID = fopen('MyFile.txt','r');
A = fscanf(fileID, ['%s' ';']); % read the header line
B = fscanf(fileID, '%d;%d/%d/%d;%d;%f;%f;%f;', [8,inf]); % read all the data into B (the date is parsed into three columns)
fclose(fileID);
B = B.'; % transpose B
% C is just for verification, can be omitted
C = datetime([B(:,4:-1:2) B(:,5)/100zeros(numel(B(:,1)),2)],'InputFormat','yyyy-MM-dd HH:mm:ss');
D = datenum(C); % Get the date in a MATLAB usable format
Titles = strsplit(A,';'); % Get column names
figure;
hold on % hold the figure for multiple plots
plot(D,B(:,6),'r')
plot(D,B(:,7),'b')
datetick('x') % Set a date tick as axis
legend(Titles{4},Titles{5}); % uses titles for legend
note the parsing of the date into C: first is the date as given by you in dd-MM-yyyy format, which I flip to the official standard of yyyy-MM-dd, then your hour, which needs to be divided by 100, then a 0 for both minutes and seconds. You might need to rip those apart when you don't have exactly hourly data. Finally transform to a regular datenum, which MATLAB can use for processing.
Which results in:
You might want to play around with the datetick format, as it's got lots of options which might appeal to you.
fileID = fopen('input.txt','r');
[A] = fscanf(fileID, ['%s' ';']); % read the header line
[B] = fscanf(fileID, '%d;%d/%d/%d;%d;%f;%f;%f;', [8,inf]); % read all the data into B (the date is parsed into three columns)
fclose(fileID);
disp(B');
Note that %d reads an integer (not a double) and %f reads a floating point number.
See fscanf for more details.

I want to read this specific csv file, using Matlab. I used textscan but I failed

csv file:
Date,Open,High,Low,Close,Volume,Adj Close
20170217,64.470001,64.690002,64.300003,64.620003,21234600,64.620003
20170216,64.739998,65.239998,64.440002,64.519997,20524700,64.519997
I used this:
fileID = fopen('table.csv');
C = textscan(fileID,'%s %f %f %f %f %d %f','Delimiter',',');
fclose(fileID);
celldisp(C)
but It does not read anything.
You can use the csvread function to read a csv file.
m=csvread('table.csv',1,0)
The values are stored in a matrix.
Since your file has an header line, you have to specify, in the call, to start reading from the second row of the file.
You can do it by adding two parameters in the call:
the first defines the row from which to start reading (notice that the index is zero base)
the second defines the column from which to start (in the case of the example, from the first)
If, nevertheless, you want to use textscan, you have to modify your code as follows:
fileID = fopen('table.csv');
% C = textscan(fileID,'%s %f %f %f %f %d %f','Delimiter',',');
C1 = textscan(fileID,'%s',2);
C2 = textscan(fileID,'%d%f%f%f%f%d%f','delimiter',',')
fclose(fileID);
You have to call textscan twice:
the first time ro read the first row (the header)
the second time to read the data
Notice in the first call the third parameter in the call: it specifies that the format (%s) has to be used twice.
This because in your header row the last word is separated by a space.
Once you've read the header row, you call textscan for the again to read the numeric values.
CSV is reading by xlsread('File');
if it is reading nan so do
[num text all]=xlsread('file');
and do for loops on text output

MATLAB: loading data with multiple types in single column

I have some data from a tide gauge I have it at the moment as a .csv file. I would like to load this data into MATLAB as I need to edit it. There are 2 columns that I am interested in, the first is a date & time column in the format [dd/mm/yyyy hh:mm] and the second is a column for tidal elevation. The tidal elevation data are primarily numbers to 3 d.p. however some of the data have letters which are used as flags. I can't use csvread because the date & time format so I changing it to a number in excel (I would prefer to keep it in date time format) but I then couldn't use csvread because it didn't like the letter flags. I tried using readtable which worked (for dates as numbers) however my tidal elevation data is stuck as in a cell as cell2mat doesn't work because I read the elevation data in in string format because of the letters.
I would basically like to know is there an easier way to get the data loaded into MATLAB as what I am doing is a real mess at the moment.
Sample Data:
28/01/1994 22:15 3.312
28/01/1994 22:30 3.057
28/01/1994 22:45 2.793
28/01/1994 23:00 2.541T
28/01/1994 23:15 2.303T
28/01/1994 23:30 2.083
28/01/1994 23:45 1.882
What I've tried:
filename = 'C:\User\Documents\Tide_Data\Fish_all.csv';
fileID = fopen(filename);
data = textread(filename,'%{dd/MM/yyyy HH:mm}D %s');
Badly formed format string, so I changed the date to a number in excel.
data = csvread(filename);
Can't read the letter T so outputs an error.
I had more code which got further before I reached a dead end but I can't reproduce it
I would suggest to read the file using textscan and then convert the date & time string to datenum and convert the last column to double if the letter exist or not.
C = textscan(fileID,'%s %s %s');
% allocate
result = zeros(7,2);
for ii = 1:7
% current date string
dateX = [C{1,1}{ii,1} C{1,2}{ii,1}];
% current number
numStr = C{1,3}{ii,1};
if sum(numStr == 'T') > 0
% remove char
numStr = regexprep(numStr,'T','');
end
% collect
result(ii,:) = [datenum(dateX, 'dd/mm/yyyyHH:MM'), str2double(numStr)];
end
You can then convert date numbers to any string format using datestr

using datenum results in not showing both strings

1. How do I read in this data properly so that the date parses properly?
I am trying to concatenate strings I read from a file but the output I get is mixed up.
The output is the x axis.Also, the spacing from x axis has numbers instead of the string I want.
The file has 4 columns,date,time,temperature and value.
The date is "01.01.2013 " and the time "09:08:02"
Also, if I want to use only first column (with date) how can I do this?
Because using datenum(mydata{1}) results to "Cannot parse date 01.01.2013"
...
mydata = textscan(fid, '%s %s %f %f', 'delimiter',';', 'HeaderLines',1);
date={};
temp={};
..
date{1}=datenum( strcat(mydata{1},{' '},mydata{2}) );
...
2. How do I correct the axis ticks?
I am then trying to plot data using plotyy and want the x-axis to be the date, but I am getting two different axis labels.
Here is the code I am using:
temp = mydata{4};
plotyy(date,temp,date,2*temp);
datetick('x','mmm.dd,yyyy');
Here is the resulting image:
---------------UPDATE---------------------------------------
Here is the code:
fid = fopen('test2.txt','r');
mydata = textscan(fid, '%s %s %f %f', 'delimiter',';', 'HeaderLines',1);
fclose(fid);
date=datenum( strcat(mydata{1},{' '},mydata{2}),'mmm.dd,yyyy HH:MM:SS' );
temperature=mydata{3};
value=mydata{4};
[AX,H1,H2]=plotyy(date,temperature,date,value,'plot');
set(get(AX(1),'Ylabel'),'String','Temperatures');
set(get(AX(2),'Ylabel'),'String','Value');
set(H1,'LineStyle','--');
set(H2,'LineStyle',':');
datetick(AX(1),'x','mmm.dd,yyyy');
title('Temperatures - Values');
xlabel('Date')
and the file
Date;Time;Temp;value
Jan.01,2013; 11:00:00;20;10
Feb.08,2013; 12:00:00;23;11
Mar.04,2013; 04:02:00;24;15
Apr.10,2013; 08:04:00;28;20
May.10,2013; 12:05:00;32;30
Jun.04,2013; 10:06:0;33;27
1. Parsing input
You are receiving the "cannot parse" error, because you are also not including a format string (formatIn). See the documentation for datenum.
If you want to convert only the first column to the date, this would look like:
date=datenum(mydata{1},'mm.dd.yyyy');
If you want to convert both the first and second columns, try:
date=datenum( strcat(mydata{1},{' '},mydata{2}),'mm.dd.yyyy HH:MM:SS');
Here is the entire code I am running, which seems to work. Note that there is no header row in my datafile.
% data.txt
% 01.01,2013; 11:00:47;10;20
% 01.02,2013; 11:00:57;10;40
fid = fopen('data.txt');
mydata = textscan(fid, '%s %s %f %f', 'delimiter',';');
date=datenum( strcat(mydata{1},{' '},mydata{2}),'mm.dd,yyyy HH:MM:SS');
2. Getting correct plots
There are two different x-ticks for plotyy command. By setting datetick in the way you did, you are only changing one of them. Instead, change first x-tick to date tick and set the second x-ticks to empty.
temp = mydata{4};
[AX,H1,H2] = plotyy(date,temp,date,2*temp);
datetick(AX(1),'x','mmm.dd,yyyy');
set(AX(2),'XTick',[])

Reading and Plotting from text files

I have some problems in reading data from text file and plotting it.The text file contains
Date; Time; Temp °C
05.08.2011; 11:00:47;23.75
05.08.2011; 11:01:21;23.69
05.08.2011; 11:01:56;25.69
05.08.2011; 11:02:16;23.63
05.08.2011; 11:02:50;23.63
05.08.2011; 11:03:24;23.63
I want to plot the Temperature values with elapsed minutes.
firstly i used
[a,b]=textread('file1.txt','%s %s','headerlines',1)
to read the data in a string and I get
'17:09:16;21.75'
After that I used
a= strread('17:08:00;21.81','%s','delimiter', ';')
to get
'17:08:00'
'21.81'
But after this I am not been able to figure out how to move forward to deal with both these strings, especially time.
I want to plot temperature with time on xaxis..but not this time the elapsed time..in this case 2 mins 37 secs.
Help needed
Thanks Aabaz.thats really a big favor..I dun why I could figure it out ..I spent so much time on it
I have some 50 files comprising this data..If i want to loop it under this code , how can accomplish it, cz i have names of the file under ROM IDs..alike 1AHJDDHUD1224.txt.
How wud pass the file names in the loop.Do I have to change the names of the files then pass them under loop.I dun knw
I have one more question that if I wanted the values to be plotted after every 60 seconds..alike as soon the data is available in text files graph is plotted , and then graph is updated after every 60 sec until some more values are available in text file
Consider the following code. It will cycle through all .DAT files in a specific directory, read the data files, then plots with a the x-axis formatted as date/time:
%# get a list of files
BASE_DIR = 'C:\Users\Amro\Desktop';
files = dir( fullfile(BASE_DIR,'*.dat') );
files = {files.name};
%# read all files first
dt = cell(numel(files),1);
temps = cell(numel(files),1);
for i=1:numel(files)
%# read data file
fname = fullfile(BASE_DIR,files{i});
fid = fopen(fname);
C = textscan(fid, '%s %s %f', 'delimiter',';', 'HeaderLines',1);
fclose(fid);
%# datetime and temperature
dt{i} = datenum( strcat(C{1},{' '},C{2}) );
temps{i} = C{3};
end
Now we can plot the data (say we had 16 files, thus layout subplots as 4-by-4)
figure
for i=1:16
subplot(4,4,i), plot(dt{i}, temps{i}, '.-')
xlabel('DateTime'), ylabel('Temp °C')
datetick('x','HH:MM:SS')
end
You can merge the time strings with sprintf and translate them to seconds with datenum. Then the rest will be easy. Here is how it could work:
fid=fopen('data','r');
header=fgetl(fid);
data=textscan(fid,'%s','delimiter',';');
fclose(fid);
data=data{:};
day=data(1:3:end);
hour=data(2:3:end);
temp=str2double(data(3:3:end));
time=cellfun(#(x) sprintf('%s %s',day{strcmpi(hour,x)},x),hour,'uniformoutput',0);
% timev=datevec(time,'mm.dd.yyyy HH:MM:SS');
timen=datenum(time,'mm.dd.yyyy HH:MM:SS');
seconds=timen*86400;
plot(seconds-seconds(1),temp);
You may want to check the date format as I did not know which format you were using, so I guessed it was mm.dd.yyyy HH:MM:SS (see Matlab date specifiers)