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.
Related
I am trying to load multiple files from a directory I created, plot them in separate figures, and then output them as .tiff files.
I believe that I have all of the code needed for plotting the loaded files and then outputting them as .tiff files, but I am unable to get the files loaded into MATLAB initially to carry out the plotting and the output.
Function used:
function x = chaos(x0, lambda, vectorLength);
x0 = 0.5;
lambda = 3.8;
vectorLength = 1500;
x = zeros(vectorLength,1);
x(1) = x0;
for k=2:vectorLength,
x(k) = lambda*x(k-1)*(1-x(k-1));
end
T = 2;
x1 = x(1:end-2*T);
x2 = x(T+1:end-T);
x3 = x(2*T+1:end);
figure('Color',[1 1 1]);
h = plot3(x1, x2, x3);
xlabel('x(t)');
ylabel('x(t+T)');
zlabel('x(t+2T)');
Code used for creating directory and file (working):
currentFolder = pwd;
mkdir('chaos');
for k = 1:30
data=chaos(k);
full_filename = fullfile(currentFolder,['\chaos\chaos' num2str(k) '.txt']);
fid = fopen(full_filename,'w' );
fprintf(fid,'%d\n',data);
fclose(fid);
end
full_filename = fullfile(currentFolder,['\chaos\chaos1.txt']);
fileID = fopen(full_filename,'r');
formatSpec = '%f';
X = fscanf(fileID,formatSpec);
plot(X);
Code used for trying to load, plot, then output files from the created directory (not working):
for k = 1:30
dir('chaos');
x = load('chaos(k).txt');
figure('Color', [1 1 1]);
plot(x);
pause(0.1);
eval(sprintf('print -dtiff chaos%d', k));
end
I am expecting to have 30 figures plotted and outputted to the screen, and then have 30 figures outputted as .tiff files. The actual output is only showing the directory in the command window, and nothing is getting plotted or outputted as .tiff files.
EDIT: here is the updated code to fix the problem with the variable k:
x = load(['chaos', num2str(k), '.txt']);
Here's an issue:
for k = 1:30
dir('chaos');
x = load('chaos(k).txt');
Variable interpolation doesn't work like that in Matlab. If you want the value held in k to go into your string, you need to use string concatenation or sprintf:
for k = 1:30
file = sprintf('chaos%d.txt', k);
x = load(file);
Looks like you're doing the right thing further down in your output code; you just need to apply it here, too.
You probably should avoid eval, too. Call it like this:
print('-dtiff', sprintf('chaos%d', k));
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',',');
M = round(csvread('noob.csv'))
save projectDAT.dat M -ascii
load projectDAT.dat
mat = (projectDAT)
rowws(mat)
This is my main script. I have a excel file, which opens up a 20 x 20 matrix in matlab. Now I have to call a function in this mainscript, which would find the sum of elements in a row for me and put them in a column vector. Here is my function:
function sumRow = sum_of_rows(mat)
[m n] = size(mat);
sumRow = zeros(m,1);
for i = 1:m;
for j = 1:n;
sumRow(i) = sumRow(i) + mat(i,j);
end
end
vec = sumRow;
end
I am required to plot a line graph using this column vector. I am supposed to call a function from the mainscript. The function should be able to take the input from this sum_of_rows function. I tried doing this:
function plotthegraph(~)
% Application for plotting the height of students
choice = menu('Choose the type of graph', 'Plot the data using a line plot', 'Plot the data using a bar plot');
if choice == 1
plot_line(sum_of_rows)
y = sum_of_rows
x = 1:length(y)
plot(x,y)
title('Bar graph')
xlabel('Number of characters')
ylabel('Number of grades')
elseif choice == 2
plot_bar(sum_of_columns)
end
Its not working out though. Can someone please help me out, I would really appreciate it.
Thank you.
Have you considered using the builtin sum function? I think
mysum = sum(mat,2)
would do the trick.
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.
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