Error in my Matlab code? - matlab

I would like to make some calculation on my Raman spectra, I have a problem to read my input file. My file .txt contain 2 columns: X = Wavelength (cm-1) and Y = Raman intensity. The name of the file contains the coordinates of the position or the Raman spectrum was collected, for example (0.00,-05.00) or (-2.00,-0.50).
function Read_Raman_Files
% Reads Raman spectra from txt files.
% Each file contains the data for a single Raman spectrum:
% X = Wavelength (cm-1)
% Y = Raman intensity
% The name of the input file contains the coordinates at which the spectrum is taken.
% Results are stored in 'data.mat'.
files = dir('-5.0,0.00.txt');
Ncurves = length(files);
if Ncurves==0, display('No txt files found!'); return; end
for i = 1:Ncurves,
i
fname = files(i).name;
data = importdata(fname);
if i==1, X = data(:,i); end
Y(:,i) = data(:,2);
dash = strfind(fname,'__');
Xpos(i) = str2num(fname(strfind(fname,'Xµm_')+4:dash(2)-1));
Ypos(i) = str2num(fname(strfind(fname,'Yµm_')+4:dash(3)-1));
end;
save('data.mat', 'Ncurves', 'X', 'Y', 'Xpos', 'Ypos');
return

Here is an example on how to read the content of a file that has 2 columns of integers separated by comma:
formatSpec = '%d%d';
[x, y] = textread('yourFile.txt', formatSpec, 'delimiter',',');

Related

Surface plot using multiple excel files

I'm just a beginner with MATLAB.
I need to represent my data using a 3D plot. I tried using the surf function but in my case this is a little bit tricky. From the code you will see that I am looping through multiple excel files to extract data from it.
Using a 3-dimensional plot I need to represent my Fv array as the 'X' coordinate, my FTsiga as the 'Y' coordinate and the the third coordinate should be each excel file that I am looping through.
A plot of (Fv,FTsiga) looks like the figure that is attached herewith.
Fv(x-axis) , FTsiga(y-axis)
The code that I have written so far couldn't seem to execute because MATLAB crashed due to insufficient memory or because it got stuck in a loop. The latter is more likely I guess.
% Matlab trial code: Trying to loop through excel files strored in directory
source_dir = 'C:\UTwente\Q4\Structural Health and Condition monitoring\Case Roadbridge (Zwartewaterbrug)\Excel data'
source_files = dir(fullfile(source_dir, '*xlsx'));
len = length(source_files);
matrix = zeros(len,32);
X = zeros(len,32); Y = zeros(len,32); Z = zeros(len,32);
%looping through excel file in directory
for i=1:len
data= xlsread(source_files(i).name,'Measurement data');
for j=1:32
sig = data(:,j);
sig = sig - mean(sig); % Remove d-c Offset
L = length(sig);
Fs = 1000; % Sampling Frequency
Fn = Fs/2; % Nyquist Frequency
FTsig = fft(sig)/L;
Fv = linspace(0, 1, fix(length(FTsig)/2)+1)*Fn; % Frequency Vector
Iv = 1:length(Fv); % Index Vector
FTsiga = double(abs(FTsig(Iv))*2); % Truncate, Magnitude, Convert To Double
sgf_sm = sgolayfilt(FTsiga, 5, 501); % Create ‘sgolayfilt’ Filtered FFT
[~, idx] = max( sgf_sm ); % Getting the value of the modal frequency
peakfreq = Fv( idx );
matrix(i,j) = peakfreq; % Matrix of all peak frequencies
[X,Y,Z] = meshgrid(Fv,FTsiga,i);
end
surf(Fv,FTsiga,i);
end

Read N integers from txt file MATLAB

I'm trying to write a script using MATLAB that reads from a txt file (which has 100*3 elements written in a single column). I want to read them 100 elements at a time and apply a fit exponential function. This is what I wrote:
defaultPath = 'my/default/path/';
prompt = 'file name? ';
fileName = input(prompt,'s');
fullPath = strcat(defaultPath,fileName);
fileID = fopen(fullPath);
for h = 1:3
buff = textscan(fileID, '%d', 100);
y=buff';
x = zeros([100, 1]);
for j = 1:100
x(j,1) = j;
end
f = fit(x,y,'exp1');
plot(f,x,y);
end
but it gives me this error :
X and Y must have the same number of rows.
Your main problem is probably that the two input vectors to fit are shaped differently: one is of size [100 1], the other [1 100], i.e. one is a column vector and the other's a row. I suggest this:
defaultPath = 'my/default/path/';
prompt = 'file name? ';
fileName = input(prompt,'s');
fullPath = strcat(defaultPath,fileName);
fileID = fopen(fullPath);
for h = 1:3
buff = textscan(fileID, '%d', 100);
y=buff{1}';
x = 1:length(y);
f = fit(x,y,'exp1');
figure; %open new window for plotting each slice of the data
plot(f,x,y);
end
fclose(fileID);
Note that I added a figure call before the plot, so that the 3 sets of data are plotted on separate figures (otherwise the default behaviour would be that each plot overwrites the previous one in the same figure.
I also changed the definition of x such that it explicitly matches the length of y, this will prevent some errors in case there were problems with the read and y has nontrivial length. Anyway, it's best to avoid magic numbers and define everything in terms of others, whenever possible.
You can use csvread as follows:
f = csvread(STRING_OF_FILE_NAME);
f will be a matrix containing the data.

Read data from file: keep separation by empty line in file

I can make a matrix x and y from data.dat which consists of 2 columns using this code:
load data.dat
x=data(:,1);
y=data(:,2);
What if I want to make matrices x1, x2, ... xn and the same with y,
where x1, x2, are based on the separation by a blank line in the file data.dat:
54.510 1.420
55.294 1.819
55.859 1.935
55.999 2.381
9.017 1.600
9.518 1.916
9.868 2.217
9.896 2.368
10.113 2.533
10.424 2.552
.... ...
Based on this data example, I expect
x1=[54.510;55.294;55.859;55.999]
x2=[9.017;9.518;9.868;9.896;10.113;10.424]
y1=[1.420;1.819;1.935;2.381]
y2=[1.600;1.916;2.217;2.368;2.533;2.552]
You can use fgets to read the data from your file. It is assumed that your file is called test.dat:
(see the comments for explanations on the functionality)
% introduce a counter for all the 'blocks in the file'
block = 1;
% initialize empty vectors for x and y
x = [];
y = [];
% open the file (in this case 'test.dat')
file = fopen('test.dat');
% read the first line of the file
tline = fgets(file);
% continue as long as there are lines in the file
while ischar(tline)
% fgets returs a string, convert to float to process:
q = str2num(tline);
% if q is empty, we have a blank line, otherwise, append the values to
% x and y
if ~isempty(q)
x(end+1) = q(1);
y(end+1) = q(2);
else
% if there is a blank line, write x and y to a cell X and Y
% you need a cell here, because the number of elements per block may
% differ
X{block} = x;
Y{block} = y;
% advance the block counter
block = block + 1;
% clear and re-initialize x and y - this is necessary because the next
% block may contain less values. you do not want artifacts.
clear x y
x = [];
y = [];
end
% read the next line
tline = fgets(file);
% at the end of the file, fgets returns not a string but a number, -1
% in this case, assign x and y to X and Y
% no need to increment block, because you are at the end of the file
if tline == -1
X{block} = x;
Y{block} = y;
end
end
% close the file once all operations are done
fclose(file);
You now have a cell X and a cell Y which contain the data from your file. E.g.
X{1} =
Columns 1 through 2
54.51 55.294
Columns 3 through 4
55.859 55.999
I am aware that you won't get variables called x1, x2, ... xn with this approach. However, I believe that cells X{1}, X{2}, ... X{n} are both easier to generate, populate and handle than individual variables.

Matlab: appending cell array

I have 10 binary files, each storing a list of numbers. I want to load each file in turn, and then append a cell array y with the numbers in that file. So if each file contains 20 numbers, I want my final cell to be 10x20. How do I do this? The following code does not work:
for i=1:10
% Load an array into variable 'x'
y = {y x}
end
You only need a minor modification to your code:
y = cell(1,10); %// initiallize if possible. Not necessary
for ii = 1:10 %// better not use i as a variable (would override imaginary unit)
%// Load an array into variable 'x'
y{ii} = x; %// fill ii-th cell with x.
%// Or use y{end+1} = x if you haven't initiallized y
end
If you are reading strictly numbers and want an array (rather than cells), this could work:
% read CSV numbers from file into array
temp = {};
out = [];
for i=1:10
% my example files were called input1.txt, input2.txt, etc
filename = strcat('input', num2str(i), '.txt');
fid = fopen(filename, 'r');
temp = textscan(fid,'%d','delimiter',',');
out(i,:) = cell2mat(temp);
fclose(fid);
end
'out' is a 10x20 array

Matlab: Color Coding a 3D Plot

I've been trying to look around online for something I want but I'm not having much luck so I thought I would just ask on here.
Is it possible to pinpoint in a different color and show the point on the graph where there are intersections between the two plots?
Thanks for any help you can give.
Here is the code:
file1 = fopen('C:\Program Files (x86)\Notepad++\avatar1.txt'); % open text file
file2 = fopen('C:\Program Files (x86)\Notepad++\avatar2.txt'); % open text file
file3 = fopen('C:\Program Files (x86)\Notepad++\avatar3.txt'); % open text file
tline1 = fgetl(file1); % read line by line and remove new line characters
tline2 = fgetl(file2); % read line by line and remove new line characters
tline3 = fgetl(file3); % read line by line and remove new line characters
% declare empty arrays
CX1 = [];
CY1 = [];
CZ1 = [];
CX2 = [];
CY2 = [];
CZ2 = [];
CX3 = [];
CY3 = [];
CZ3 = [];
while ischar(tline1) % true if tline is a character array
temp = cell2mat(textscan(tline1, '<%n,%n,%n>'));
% convert all the cell fields to a matrix
CX1 = vertcat(CX1, temp(1));
CY1 = vertcat(CY1, temp(2));
CZ1 = vertcat(CZ1, temp(3));
tline1 = fgetl(file1);
end
while ischar(tline2) % true if tline is a character array
temp = cell2mat(textscan(tline2, '<%n,%n,%n>'));
% convert all the cell fields to a matrix
CX2 = vertcat(CX2, temp(1));
CY2 = vertcat(CY2, temp(2));
CZ2 = vertcat(CZ2, temp(3));
tline2 = fgetl(file2);
end
while ischar(tline3) % true if tline is a character array
temp = cell2mat(textscan(tline3, '<%n,%n,%n>'));
% convert all the cell fields to a matrix
CX3 = vertcat(CX3, temp(1));
CY3 = vertcat(CY3, temp(2));
CZ3 = vertcat(CZ3, temp(3));
tline3 = fgetl(file3);
end
fclose(file1); % close the file
fclose(file2); % close the file
fclose(file3); % close the file
plot3(CX1, CY1, CZ1) % plot the data and label the axises
plot3(CX2, CY2, CZ2)
plot3(CX3, CY3, CZ3)
xlabel('x')
ylabel('y')
zlabel('z')
grid on
axis square
rotate3d on; % activate interactive mouse rotation
Changing the colours is simple, that's just a case of adding a colour code to the plot3 command, e.g.:
plot3(CX1, CY1, CZ1, 'b'); % blue lines/markers
plot3(CX2, CY2, CZ2, 'r'); % red lines/markers
plot3(CX3, CY3, CZ3, 'g'); % green lines/markers
For more details on colour codes, see the Matlab Colourspec Page.
The intersection could be a bit more tricky, depending on whether you want the intersection of the points (i.e. specific points which appear in all 3 datasets) or the intersection points of the lines that join the points.
I think the former should be fairly easy (this is untested and assumes CX1,etc are vertical vectors):
figure; % Open up a new figure
hold on; % This means the everything you plot stays in the figure and is not overwritten
% Plot the original points
plot3(CX1, CY1, CZ1, '-*b'); % blue lines/markers
plot3(CX2, CY2, CZ2, '-*r'); % red lines/markers
plot3(CX3, CY3, CZ3, '-*g'); % green lines/markers
% turn those 1xn vectors into 3xn matrices for each set of points
points1 = [CX1, CY1, CZ1];
points2 = [CX2, CY2, CZ2];
points3 = [CX3, CY3, CZ3];
% Find the intersection of the 3 sets
CX_intersect = intersect( points1, intersect( points2, points3, 'rows'), 'rows');
% Draw a scatter plot of the intersection points. the 'mo' means:
% m: magenta in colour, o: circular markers
scatter3( CX_intersect(:,1),CX_intersect(:,2),CX_intersect(:,3),'mo');
The intersection works like so:
Say we have 3 matrices, each containing a number of 3d points. Let's call them A,B and C.
To find the intersection between all 3 sets we first find the points that intersect just in A and B. We now have a set of points that we know are in A and B, so now we just have to check if those points are in C as well. we do this by doing another intersection.
I just chained those together into one line of code, which was probably not very useful, so I apologise. The code for the A,B,C intersections is below:
D = intersect(A,B,'rows') % we use rows because each row represents a 3D point
E = intersect(C,D,'rows') % E is the intersection of the 3 sets.
We can then substitute D into the line E = ... and we get:
E = intersect( intersect(A,B,'rows'), C, 'rows' );
Hope that helps!