Plot loop n variables
Show older comments
Hello Community,
I have been trying to create a plot of several arrays in loops, but I have problems assigning the change of name of the variable to the plot. Also if you know how to assign the legend name according to the plot it would be great. So, I have A1,A2,A3,... and B1,B2,B3,... respectively each pair makes a plot. So far I have written: Arrays A, B are a size (5x10000), and I'm trying to plot the second column of A (date) with the second column of B with:
%nrows is the number of pairs of A and B
for i=1:nrows
x=datetime(A{i}(:,2)', 'ConvertFrom', 'datenum');
y=B{i}(:,2)';
figure
plot(x,y);
xlabel('A');ylabel('B'); grid on; grid minor; legend ('B',num2str(i));
hold on
end
The error that I get is "Undefine variable A or Class A"
Any help is very appreciated. Thanks
5 Comments
John D'Errico
on 18 Aug 2017
Yet another reason why making numbered variables like this is foolish, terribly bad programming style.
Learn how to use arrays.
per isakson
on 18 Aug 2017
Edited: per isakson
on 18 Aug 2017
@Jorge
- A and B are they variables alongside A1,A2,A3,... and B1,B2,B3,.. in the base workspace?
- y=B{i}(:,2) hints that B is a cell array
- this for-loop is it part of a script or a function ?
- if in a script, please run whos A B and show us the result!
- if in a function, do you pass A and B to this function?
"...but I have problems assigning the change of name of the variable to the plot.... So, I have A1,A2,A3,... and B1,B2,B3,..."
Of course you will have problems if you have numbered your variables: using numbered variables means that you are writing slow, inefficient, obfuscated, buggy, hard-to-debug code. Some other beginners will tell you that that is okay, but it is really very simple to write neat and efficient code: use indexing instead of numbered variables. All experts and experienced MATLAB users will tell you to use indexing, and you should seriously consider following their advice.
This is what the MATLAB documentation has to say about trying to access numbered variables: "A frequent use of the eval function is to create sets of variables such as A1, A2, ..., An, but this approach does not use the array processing power of MATLAB and is not recommended. The preferred method is to store related data in a single array"
You should read these:
etc, etc.
In your last question you should have used the answer using accumarray, which would split your array into a cell array, and then you can access the cell array data using indexing.
DO NOT USE NUMBERED VARIABLES.
Image Analyst
on 18 Aug 2017
I'm wondering if per is right and he just has two cell arrays A and B, and when he wrote A1, A2, etc. he really meant A(1}, A{2}, etc. In fact his code tries to reference A like that, but it appears the problem is that A was never defined/created/passed-in in the first place.
Jorge Rodriguez
on 18 Aug 2017
Accepted Answer
More Answers (1)
John BG
on 18 Aug 2017
Hi Mr Rodriguez
while it's a good general guideline to try to work with variables that use matrix indices instead of putting the index in the name of the variable, it's a common practice, it happens, and since you already have the data in such format, let's work with what we've go available:
1.
Let's say you have the following
A1 =
1.4897 1.4172
1.4090 0.6715
>> A2
A2 =
-1.2075 1.6302
0.7172 0.4889
>> A3
A3 =
1.0347 -0.3034
0.7269 0.2939
>> B1
B1 =
-0.8095 1.4384
-2.9443 0.3252
>> B2
B2 =
-0.7549 -1.7115
1.3703 -0.1022
>> B3
B3 =
-0.2414 0.3129
0.3192 -0.8649
2.
now capture the names of the variables of interest
S=whos
S =
10×1 struct array with fields:
name
size
bytes
class
global
sparse
complex
nesting
persistent
S.name
ans =
'A'
ans =
'A1'
ans =
'A2'
ans =
'A3'
ans =
'AB'
ans =
'B1'
ans =
'B2'
ans =
'B3'
ans =
'S'
ans =
'ans'
3.
Now have the choice to either
3.1.- work with the names of the variables contained in, for instance
D={S.name}
D =
1×10 cell array
'A1' 'A2' 'A3' 'AB' 'B1' 'B2' 'B3' 'D' 'S' 'ans'
there may not be need for a cell, but if you have more than 9 pairs A B then the length of the variable names varies with the increasing numerals
3.2.- or use the code you have already included in your question
A={}
for k=1:1:length(D)
if findstr(D{k},'A')
A=[A;D{k}]
end
end
B={}
for k=1:1:length(D)
if findstr(D{k},'B')
B=[B;D{k}]
end
end
now you can start working on the plots mentioned in the question, or any other processing
if you find this answer useful would you please be so kind to consider marking my answer as Accepted Answer?
To any other reader, if you find this answer useful please consider clicking on the thumbs-up vote link
thanks in advance
John BG
5 Comments
Stephen23
on 18 Aug 2017
Note that using whos (or any other introspective programming) is highly inefficient and is not recommended by any MATLAB experts or by the MATLAB documentation: "Avoid functions that query the state of MATLAB such as inputname, which, whos, exist(var), and dbstack. Run-time introspection is computationally expensive"
Using this method will also lead very inefficient accessing of those variables, which is not recommended by any MATLAB experts or by the MATLAB documentation: "A frequent use of the eval function is to create sets of variables such as A1, A2, ..., An, but this approach does not use the array processing power of MATLAB and is not recommended"
Read this to know more about why this is a buggy, inefficient way to write code, and what the better alternatives are (hint: indexing):
Stephen hits the point again. The problem of numbered names has been discussed very often already and avoiding them is strongly recommended.
The iterative growing of arrays in the paragraph "3.2" in the above answer is very inefficient and a standard case for a bad programming pattern.
Walter Roberson
on 18 Aug 2017
If you whos a symbolic variable then MATLAB will ask the symbolic engine what the size of the variable is, which can take a long time to compute in some cases. I hit a situation where it took whos about 7 minutes to figure out the size of a symbolic variable. The size information is not cached on the MATLAB side, so that was 7 minutes every time that the size was asked for.
it will be 'long' as in 'langsam' if the name of the variable is complicated and there are many complicated variable names.
But how complicated and slow can it be to retrieve A1 A2 .. and B1 B2 ..
People come on, when Coberdick and Simon say 'slow' without bringing any time measurement, what's the point?
"Slow" means, that using arrays instead of a set of variables with numbered names will be "faster" - measured in runtime and taking into account the the time for programming, debugging and maintaining the code.
You find enough arguments to get the point e.g. in https://www.mathworks.com/matlabcentral/answers/304528-tutorial-why-variables-should-not-be-named-dynamically-eval.
Categories
Find more on Code Performance in Help Center and File Exchange
Products
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!