Plot selected variables according to flag

11 views (last 30 days)
Thales
Thales on 4 May 2017
Edited: dpb on 5 May 2017
I have three variables
x1, x2 and x3
and vector, say,
flag = [1 0 1]
If I want to plot on the same figure x1, x2 and x3, but only if flag(i) == 1, how can I do it without using if-else and switch-case?
I'm looking for a more compact way of writing:
figure; hold on;
if (flag(1))
plot(x1)
elseif (flag(2))
plot(x2)
elseif (flag(3))
plot(x3)
end
Also, how do I add a legend to the plot, that changes with the number of variables plotted?
  1 Comment
Stephen23
Stephen23 on 5 May 2017
Creating lots of separate variables will make your code more complex than it needs to be. When you put all of your data together into one array (numeric, cell, struct, table,...) then accessing it is trivial using indexing or fieldnames.

Sign in to comment.

Accepted Answer

dpb
dpb on 4 May 2017
Edited: dpb on 5 May 2017
"I have three variables x1, x2 and x3..."
And there's the crux of the problem--do NOT create sequentially-name variables in Matlab; use arrays instead--
x=[x1 x2 x3]; % put the data together
flag=logical([1 0 1]); % the addressing logical array...
plot(x(flag,:)) % and plot those wanted
Above does assume each has same number of elements so can concatenate into double array; if they're of disparate lengths then either pad shorter with NaN to length of longest or can do similar addressing with cell arrays where each cell contains one of the arrays. But, "keep it simple" is the first rule until reach a real need for more complex solutions.
ADDENDUM
Well, as noted in the comment, using a state variable array solution is the most concise.
The next level of complexity that gives you most of what you're looking for would be a structure with named fields that match up to what your variable names are.
There, you can then refer to names dynamically as in
>> s=struct('position',1,'velocity',2,'accel',3)
s =
position: 1
velocity: 2
accel: 3
>> s.velocity % address single field
ans =
2
>> names=fieldnames(s) % can get fieldnames dynamically...
names =
'position'
'velocity'
'accel'
>> flag=logical([1 0 1]); % the logical vector again...
>> for i=names(flag).' % address those dynamically
s.(char(i))
end
ans =
1
ans =
3
>> s.accel=linspace(0,1,3) % fields can hold vectors, other
s =
position: 1
velocity: 2
accel: [0 0.5000 1]
>>
  2 Comments
Thales
Thales on 4 May 2017
I tried to simplify the question, but I have three variables because x1 is position, x2 is velocity and x3 is acceleration. Also, the number of rows of this variables is equal the numbers of degree-of-freedom of the system, so to make the code more readable, I separate the three variables, to write according to our textbook on dynamics. I am not using the ode functions to integrate the system, is a kinematics analysis, so I am not saving the variable and its derivatives on the same array.
dpb
dpb on 4 May 2017
Well, "there is no free lunch!". :)
If you use named variables, the issue becomes one of accessing them by name as you've observed and it takes conditional code to do so. Using a state variable is one solution as outlined above.

Sign in to comment.

More Answers (0)

Categories

Find more on 2-D and 3-D Plots in Help Center and File Exchange

Tags

Community Treasure Hunt

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

Start Hunting!