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

1 view (last 30 days)
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 Comments
Stephen23
Stephen23 on 20 Apr 2020
Edited: Stephen23 on 20 Apr 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 on 20 Apr 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?

Sign in to comment.

Accepted Answer

Stephen23
Stephen23 on 20 Apr 2020
Edited: Stephen23 on 20 Apr 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 Comments
Victoria Dutch
Victoria Dutch on 20 Apr 2020
Edited: Victoria Dutch on 20 Apr 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 on 20 Apr 2020
Edited: Stephen23 on 20 Apr 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.

Sign in to comment.

More Answers (0)

Categories

Find more on Structures in Help Center and File Exchange

Products


Release

R2019a

Community Treasure Hunt

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

Start Hunting!