Borrar filtros
Borrar filtros

Plotting from a Loop - "Error: This statement is incomplete"

1 visualización (últimos 30 días)
Victoria Dutch
Victoria Dutch el 20 de Abr. de 2020
Editada: Victoria Dutch el 20 de Abr. de 2020
I'm trying to plot a tier of my structural array with the following code:
for site = 1:19
plot((eval(sprintf('TVC_ForPointCLM.SMP.Profiles.%.force'))),(eval(sprintf('TVC_ForPointCLM.SMP.Profiles.%.depth_smp'))));
hold on
end
hold off
xlabel('Force (N)')
ylabel ('Distance from SMP initialisation (mm)')
When I run this, I get a message saying "Error: This statement is incomplete." about the 2nd line of the code. I've double checked the parenthesis match, so that's not it, but I'm not sure what else would cause this error.
TVC_ForPointCLM is the structural array, and then there are 19 profiles where % is subsituted into the variable name.
  4 comentarios
Stephen23
Stephen23 el 20 de Abr. de 2020
Editada: Stephen23 el 20 de Abr. de 2020
The more efficient and robust method is to use dynamic fieldnames:
Avoiding eval would help you to debug your code and avoid basic errors in your code.
Victoria Dutch
Victoria Dutch el 20 de Abr. de 2020
Following the documentation for dynamic fieldnames, I've edited the code to the following:
for site = 1:19
plot(('TVC_ForPointCLM.SMP.Profiles.SMP_(site).force')),(('TVC_ForPointCLM.SMP.Profiles.SMP_(site).depth_smp'));
hold on
end
When I run this, it displays "Error using plot: Invalid first data argument.". It's not just because the fields are are named SMP_01 to SMP_19, as I tried running it for just sites 10:19, and got the same error (though that is going to be an issue).
Help?

Iniciar sesión para comentar.

Respuesta aceptada

Stephen23
Stephen23 el 20 de Abr. de 2020
Editada: Stephen23 el 20 de Abr. de 2020
You are still writing the whole thing as a character vector. I don't see any examples in the documentation like that:
Also the dynamic fieldname must be the entire name of a field, not just part of it like you tried. For example:
fnm = sprintf('SMP_%d',site);
TVC_ForPointCLM.SMP.Profiles.(fnm).force
  2 comentarios
Victoria Dutch
Victoria Dutch el 20 de Abr. de 2020
Editada: Victoria Dutch el 20 de Abr. de 2020
Thanks! I ran the following and it works perfectly.
for site = 10:19
fnm = sprintf('SMP_%d',site);
plot(TVC_ForPointCLM.SMP.Profiles.(fnm).force,TVC_ForPointCLM.SMP.Profiles.(fnm).depth_smp);
hold on
end
However, when I tried the same principle for the fieldnames SMP_01 ... SMP_09, using this code below:
for site = 1:9
fnm = sprintf('SMP_0%d',site);
plot(TVC_ForPointCLM.SMP.Profiles.(fnm).force,TVC_ForPointCLM.SMP.Profiles.SMP_(site).depth_smp);
hold on
end
I get this error:
"Reference to non-existent field 'SMP_0'.
Error in SMP_figure_loop (line 3): plot(TVC_ForPointCLM.SMP.Profiles.SMP_0(site).force,TVC_ForPointCLM.SMP.Profiles.SMP_(site).depth_smp);"
If run the first code for sites 1:19, I get the same error but for SMP_1 as I'm trying to plot a field that doesn't exist.
Stephen23
Stephen23 el 20 de Abr. de 2020
Editada: Stephen23 el 20 de Abr. de 2020
"as I'm trying to plot a field that doesn't exist. "
That is because it doesn't exist.
"when I tried the same principle for the fieldnames SMP_01 ... SMP_09... I get this error"
That isn't the same syntax.
You are (again) trying to use the dynamic fieldname syntax on just part of the fieldname:
.SMP_0(site).
This syntax is interpreted as
.SMP_0(site).
^^^^^ % Fieldname = "SMP_0" (note: not dynamic!).
^^^^^^ % Indexing into an array stored in that field.
And clearly the field SMP_0 does not exist in your structure, thus the error. Compare and note where the parentheses are relative to the period characters (hint: directly adjacent):
.SMP_0(site). % what you tried
.(fnm). % what I gave you and what is shown in the documentation
Exactly as I wrote in my answer, the dynamic fieldname syntax applies only the the entire fieldname, not just part of it as you are trying. That is what the sprintf is for: it lets you define the entire fieldname as a character vector, and then you simply use its output as the entire dynamic fieldname.
fnm = sprintf('SMP_0%d',site);
TVC_ForPointCLM.SMP.Profiles.(fnm).force
Tip: you can easily define a format string which prints two digits and a leading zero when required:
fnm = sprintf('SMP_%02d',site);
then you can use exactly the same code for the different ranges of values, or all of those values in one loop.

Iniciar sesión para comentar.

Más respuestas (0)

Categorías

Más información sobre Loops and Conditional Statements en Help Center y File Exchange.

Productos


Versión

R2019a

Community Treasure Hunt

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

Start Hunting!

Translated by