所以我有一个迭代循环,它从MATLAB的活动文件夹中的.csv文件中提取数据并绘制它。我想更进一步,在两个文件夹上运行脚本,每个文件夹都有自己的.csv文件。
一个文件夹称为压力,另一个压力。顾名思义,它们包含几个样本的压力和应变数据的.csv文件,每个样本称为 E3-01 , E3-02 , E3 -03 等。换句话说,两个文件夹具有相同数量的文件和相同的名称。
我看到它的方式,该过程将包含以下步骤:
就像我说的,我已经有了一个可以找到正确的列并提取数据的脚本。我不确定的是如何告诉MATLAB替换正在运行脚本的文件夹。
而不是脚本,功能会更好吗?接受4个输入的东西:两个文件夹的名称和要提取的列?
编辑:道歉,这是我到目前为止的代码:
clearvars;
files = dir('*.csv');
prompt = {'Plot name:','x label:','y label:','x values:','y values:','Points to eliminate:'};
dlg_title = 'Input';
num_lines = 1;
defaultans = {'Title','x label','y label','Surface component 1.avg(epsY) [True strain]','Stress','0'};
answer = inputdlg(prompt,dlg_title,num_lines,defaultans);
name_plot = answer{1};
x_label = answer{2};
y_label = answer{3};
x_col = answer{4};
y_col = answer{5};
des_cols = {y_col,x_col};
smallest_n = 100000;
points_elim = answer{6};
avg_x_values = [];
avg_y_values = [];
for file = files'
M=xlsread(file.name);
[row,col]=size(M);
if smallest_n > row
smallest_n = row;
end
end
smallest_n=smallest_n-points_elim;
avg_x_values = zeros(smallest_n,size(files,1));
avg_y_values = zeros(smallest_n,size(files,1));
hold on;
set(groot, 'DefaultLegendInterpreter', 'none');
set(gca,'FontSize',20);
ii = 0;
for file = files'
ii = ii + 1;
[n,s,r] = xlsread(file.name);
colhdrs = s(1,:);
[row, col] = find(strcmpi(s,x_col));
x_values = n(1:end-points_elim,col);
[row, col] = find(strcmpi(s,y_col));
y_values = n(1:end-points_elim,col);
plot(x_values,y_values,'DisplayName',s{1,1});
avg_x_values(:,ii)=x_values(1:smallest_n);
avg_y_values(:,ii)=y_values(1:smallest_n);
end
ylabel({y_label});
xlabel({x_label});
title({name_plot});
colormap(gray);
hold off;
avg_x_values = mean(avg_x_values,2);
avg_y_values = mean(avg_y_values,2);
plot(avg_x_values,avg_y_values);
set(gca,'FontSize',20);
ylabel({y_label});
xlabel({x_label});
title({name_plot});
编辑2:@Adriaan我尝试编写以下函数来从文件中获取列:
function [out_col] = getcolumn(col,file)
file = dir(file);
[n,s,r] = xlsread(file.name);
colhdrs = s(1,:);
[row, col] = find(strcmpi(s,col));
out_col = n(1:end,col);
end
但我收到了错误
Function 'subsindex' is not defined for values of class 'struct'.
Error in getcolumn (line 21)
y = x(:,n);
不确定原因。
答案 0 :(得分:1)
当然,你可以做到这两点,主要取决于偏好,只要你是脚本的唯一用户。如果其他人也将使用它,请使用函数,因为它们可以包含适当的帮助文件,然后调用help functionname
将为您提供帮助。
例如:
folders1 = dir(../strain/*)
folders2 = dir(../stress/*)
for ii 1 = 1:numel(folders)
operand1 = folders1{ii};
operand2 = folders2{ii};
%... rest of script
%
% Or function:
data = YourFunction(folders1{ii},folders2{ii})
end
总而言之,你可以同时使用两者,虽然从经验上我发现函数最终更容易使用,因为你只是传递参数而不需要遍历完整的代码来改变每次运行的参数。
此外,您可以对程序中执行修复任务的小部分进行分区。如果嵌套函数,最后只调用脚本中的单个函数,则每次运行脚本时都不必查看数百行代码,而只需运行单个函数(可以也可以在脚本或函数中, ad infinitum )。
最后,一个函数有自己的范围;这意味着该函数中的任何变量都保留在该函数中,除非您明确将它们设置为输出(除global
变量外,但这些变量仍有问题)。根据代码的其余部分,这可能是一件好事,也可能是一件坏事。如果你的函数会输出~20个变量进行进一步处理,那么函数可能应该包含更多的步骤。如果你创建了很多中间变量(我总是这样做),这将是一件好事,因为当函数完成运行时,该函数的范围将从内存中删除,从而节省了{{1}等你脚本中的每几行。
对于脚本,支持的参数是更容易调试;你不需要clear tmpVar1 tmpVar2 tmpVar3
并且可以通过脚本更容易一步,检查所有变量。但是,在调试完成之后,这个论点变得毫无意义,因此通常我会先编写一个脚本,一旦它按照需要执行,我会以最小的额外努力将其重新编写为函数。