How to plot data for hundreds of rows in MATLAB?

I am studying a flow going through an orifice.
I am aimed at overlapping the plots for the speed distribution over the vertical width profile (which is 0.015 m long; highlighted in red) for two downstream, horizontal distances [w.r.t. the orifice]: 0.01 m and 0.03 m.
The result should look as follows (the highest peak corresponds to 0.01m width profile)
I have the data for both downstream distances (in csv format, here you can find it https://drive.google.com/drive/folders/1CgeDuCahVZvLXXkNkGWlPg8lSGyurmI3).
Let me create two tables, first related to 0.01m data and second to 0.03 m. For the sake of simplicity I only include three row data. The columns labeled - contain irrelevant data for this particular problem.
Let's draw our attention to how to code this in MATLAB. The algorithm I have in mind is:
0) Optimize the given table: eliminate first and last rows (the velocity there is zero due to no-slip condition on the walls)
1) Read the velocity data from the csv table and compute the speed ##U = \sqrt{U_0^2 + U_1^2 + U_2^2}## for each data row.
2) Store the speed and width values in variables.
3) Repeat 2) and 3) for the other csv file.
4) Ready to plot.
I managed to write a code that works for the three-rows-of-data tables above
Ai = readtable("sampleData10mm.csv"); %step 0)
Bi = readtable("sampleData30mm.csv"); %step 0)
A = Ai(2:1000,:); %step 0)
B = Bi(2:1000,:); %step 0)
fComr1 = A{1:1,"U_0"}; %step 1)
sComr1 = A{1:1,"U_1"}; %step 1)
tComr1 = A{1:1,"U_2"}; %step 1)
fComr2 = A{2:2,"U_0"}; %step 1)
sComr2 = A{2:2,"U_1"}; %step 1)
tComr2 = A{2:2,"U_2"}; %step 1)
fComr3 = A{3:3,"U_0"}; %step 1)
sComr3 = A{3:3,"U_1"}; %step 1)
tComr3 = A{3:3,"U_2"}; %step 1)
Ur1 = sqrt(fComr1^2 + sComr1^2 + tComr1^2); %step 1)
Ur2 = sqrt(fComr2^2 + sComr2^2 + tComr2^2); %step 1)
Ur3 = sqrt(fComr3^2 + sComr3^2 + tComr3^2); %step 1)
speed = [0;Ur1;Ur2;Ur3]; %step 2)
width = [0;A{1:1,"Points_2"}+0.0075;A{2:2,"Points_2"}+0.0075;A{3:3,"Points_2"}+0.0075]; %step 2); Note I added +0.0075 because we want to have data from 0 to 0.016 mm in the x axis
fComr1_30mm = B{1:1,"U_0"}; %step 3)
sComr1_30mm = B{1:1,"U_1"}; %step 3)
tComr1_30mm = B{1:1,"U_2"}; %step 3)
fComr2_30mm = B{2:2,"U_0"}; %step 3)
sComr2_30mm = B{2:2,"U_1"}; %step 3)
tComr2_30mm = B{2:2,"U_2"}; %step 3)
fComr3_30mm = B{3:3,"U_0"}; %step 3)
sComr3_30mm = B{3:3,"U_1"}; %step 3)
tComr3_30mm = B{3:3,"U_2"}; %step 3)
Ur1_30mm = sqrt(fComr1_30mm^2 + sComr1_30mm^2 + tComr1_30mm^2); %step 3)
Ur2_30mm = sqrt(fComr2_30mm^2 + sComr2_30mm^2 + tComr2_30mm^2); %step 3)
Ur3_30mm = sqrt(fComr3_30mm^2 + sComr3_30mm^2 + tComr3_30mm^2); %step 3)
speed_30mm = [0;Ur1_30mm;Ur2_30mm;Ur3_30mm]; %step 3)
width_30mm = [0;B{1:1,"Points_2"}+0.0075;B{2:2,"Points_2"}+0.0075;B{3:3,"Points_2"}+0.0075]; %step 3)
figure %step 4)
plot(width,width_30mm,speed,speed_30mm) %step 4)
legend({'0.01 m', '0.03 m'},'Location','northwest') %step 4)
xlabel('width [m]') %step 4)
ylabel('U magnitude [m/s]') %step 4)
axis square; %step 4)
grid on; %step 4)
The issue I have is that I do not see how to write a code that does it for the 1000 rows. I guess there has to be a way of automatizing the whole process...
Thank you in advance! :)

 Risposta accettata

hello
mamma mia ! You are not using matlab capabilities to do math on arrays ... there is much simpler ways to do all this stuff.
demo below
  • first the hard work is done in a function so I can reuse it multiple times for different csv files
  • second, a for loop is used to repeat the same process automatically by screening your directory, finding the right csv files and sorting them in ascending order (what matlab does not do well => need to download the FEX submission files :
hope it helps
%% read multiple files
P = pwd; % currrent directory
S = dir(fullfile(P,'sampleData*.csv')); % get list of files in directory
fileNames_sorted = natsortfiles({S.name}); % sort file names into order (https://fr.mathworks.com/matlabcentral/fileexchange/47434-natural-order-filename-sort)
nFiles = numel(fileNames_sorted);
figure %step 4)
hold on
for k = 1:nFiles
filename = fullfile(P, fileNames_sorted{k});
[width,speed] = do_thejob(filename);
plot(width,speed)
end
hold off
%%% functions %%%
function [width,speed] = do_thejob(filename)
Ai = readmatrix(filename); %step 0)
[m,n] = size(Ai);
A = Ai(2:m-1,:); %step 0)
fComr = A(:,1); %step 1)
sComr = A(:,2); %step 1)
tComr = A(:,3); %step 1)
Ur = sqrt(fComr.^2 + sComr.^2 + tComr.^2); %step 1)
speed = [0;Ur]; %step 2)
width = [0;A(:,n)+0.0075]; %step 2); Note I added +0.0075 because we want to have data from 0 to 0.016 mm in the x axis
end

5 Commenti

added some legend to the graph
%% read multiple files
P = pwd; % currrent directory
S = dir(fullfile(P,'sampleData*.csv')); % get list of files in directory
fileNames_sorted = natsortfiles({S.name}); % sort file names into order (https://fr.mathworks.com/matlabcentral/fileexchange/47434-natural-order-filename-sort)
nFiles = numel(fileNames_sorted);
figure %step 4)
hold on
for k = 1:nFiles
tmp = fileNames_sorted{k};
leg_str{k} = ['D = ' num2str(tmp(11:length(tmp)-4))];
filename = fullfile(P, fileNames_sorted{k});
[width,speed] = do_thejob(filename);
plot(width,speed)
end
legend(leg_str);
hold off
%%% functions %%%
function [width,speed] = do_thejob(filename)
Ai = readmatrix(filename); %step 0)
[m,n] = size(Ai);
A = Ai(2:m-1,:); %step 0)
fComr = A(:,1); %step 1)
sComr = A(:,2); %step 1)
tComr = A(:,3); %step 1)
Ur = sqrt(fComr.^2 + sComr.^2 + tComr.^2); %step 1)
speed = [0;Ur]; %step 2)
width = [0;A(:,n)+0.0075]; %step 2); Note I added +0.0075 because we want to have data from 0 to 0.016 mm in the x axis
end
Enlightening answer Mathieu! Aswers like yours make me want to learn MATLAB more and more!
I am trying to modify my code to get the same result. I have this (I sticked to table instead of matrix form)
clc
close all
clear all
warning('OFF', 'MATLAB:table:ModifiedAndSavedVarnames')
%step 0
Ai = readtable("sampleData10mm.csv");
Bi = readtable("sampleData30mm.csv");
A = Ai(2:1000,:);
B = Bi(2:1000,:);
%step 1
fCom_10mm = A{:,"U_0"};
sCom_10mm = A{:,"U_1"};
tCom_10mm = A{:,"U_2"};
width_10mm = A{:,"Points_2"};
U_10mm = sqrt(fCom_10mm.^2 + sCom_10mm.^2 + tCom_10mm.^2);
%refined_width_10mm = [0;A(:,"Points_2")+0.0075];
%refined_width_10mm = A{:,"Points_2"+0.0075};
%step 2
fCom_30mm = B{:,"U_0"};
sCom_30mm = B{:,"U_1"};
tCom_30mm = B{:,"U_2"};
width_30mm = B{:,"Points_2"};
U_30mm = sqrt(fCom_30mm.^2 + sCom_30mm.^2 + tCom_30mm.^2);
%refined_width_30mm = [0;B(:,"Points_2")+0.0075];
%refined_width_30mm = B{:,"Points_2" + 0.0075};
%step 3
figure
plot(width_10mm,U_10mm,width_30mm,U_30mm)
%plot(refined_width_10mm,U_10mm,refined_width_30mm,U_30mm)
legend({'0.01 m', '0.03 m'},'Location','northwest')
xlabel('width [m]')
ylabel('U magnitude [m/s]')
axis square;
grid on;
Yields the desired result except for a small detail: I want the zero at the x-y intersection and not halfway the +ive x axis. You see my commented attempts to do so, refining the width. None of them work.
Particularly,
refined_width_10mm = [0;A(:,"Points_2")+0.0075]
yields an error stating that scalars cannot be added to table values.
Do you see a way of getting the same x axis as your code does (based on mine)? :)
hello
yes matlab is a nice tool for who wants to do a lot of data processing.
it takes a bit of time to understand and get used to all the tricks , but that's the benefit of being on this forum - it makes you progress much faster. That wasmy case too and I'm still learning
to come back to your code , I am not sure why you want to stick with table type data. In your case I don't see the benefit vs simply working with numerical arrays (that's why I replaced readtable with readmatrix which is also faster in many cases)
and yes you cannot directly do this
refined_width_10mm = [0;A(:,"Points_2")+0.0075]
because you"re mixing numerical arrays (0 and 0.0075) with table type data (A(:,"Points_2"))
you have first to convert all table data into arrays with table2array before doing the above code
refined_width_10mm = [0;table2array(A(:,"Points_2"))+0.0075]
It works now, really appreciate the discussion! :)
as always, my pleasure !!

Accedi per commentare.

Più risposte (0)

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by