I have a list of variables (different sized numeric matrices) named Reach1 to Reach7
I want to plot them all as subplots in one figure.
Need a way to loop over each variable as below:
names = {'Reach1' 'Reach2' 'Reach3' 'Reach4' 'Reach5' 'Reach6' 'Reach7'};
for index = 1:7
subplot(3,3,index)
plot(names(index)(:,1),names(index)(:,2));hold on;
plot(names(index)(:,5),names(index)(:,6));
plot(names(index)(:,9),names(index)(:,10));hold off;
end
Is there a better way to do this in matlab?
You cannot access names(index) because it is cell array and those are accessed by names{index}.
If you want to access variable Reach1(1,3) by calling names{1}(1,3), you will fail because Matlab will (try to) return a as an element of char array. This approach can be achieved by eval but do NOT do that! It has many drawbacks and no benefit.
You can simplify your code using Matlabs features, that are not obvious but bloody useful.
Suppose we have all matrices in one cell array Reaches={<Reach1>;<Reach2>;...}:
Reaches={rand(4,12);rand(6,12);rand(8,12);rand(2,12);rand(9,12)}; %declare dummy variables
counter=0;
for Reach=Reaches
counter=counter+1;
subplot(3,3,counter);
plot(Reach(:,[1,5,9]),Reach(:,2,6,10));
end
This code benefits from:
for is able to loop over array elements.
plot is able to process arrays.
(Advanced) Array indexing.
In this example appropriate element names{ii} is passed to Reach variable, counter counter is advanced and plot is supported by matrices containig columns 1, 5 and 9 and 2, 6 and 10 as x and y values, respectively.
Related
I have matchcounts (5x5)cell, every cell has a vector of double [106x1]. The vectors of double have zeros and non zero values. I want to find non zero values for every cell, count them and put the result in a matrix.
I tried with this code:
a{i,j}(k,1)=[];
for k=1:106
for i=1:5
for j=1:5
if (matchcounts{i,j}(k,1))~=0
a{i,j}=a{i,j}(k,1)+1;
end
end
end
end
and others but it's not correct! Can you help me? Thanks
While it is possible to fix your answer above, I recommend to change the data structure to have a much simpler solution possible. Instead of having a 2D cell array which holds 1D data, choose a single 3D data structure.
For an optimal solution you would change your previous code code to directly write the 3D-matrix, instead of converting it. To get started, this code converts it so you can already see how the data structure should look like:
%convert to matrix
for idx=1:numel(matchcounts)
matchcounts{idx}=permute(matchcounts{idx},[3,2,1]);
end
matchcounts=cell2mat(matchcounts);
And finding the nonzero elements:
a=(matchcounts~=0)
To index the result, instead of a{k,l}(m,1) you use a(k,l,m)
To give you some rule to avoid complicated data structures in the future. Use cell arrays only for string data and data of different size. Whenever you have a cell array which contains only vectors or matrices of the same size, it should be a multidimensional matrix.
I'm writing an piece of software within Matlab. Here, the user can define a dimension say 3.
This dimension is subsequently the number of iterations of a for loop. Within this loop, I construct a matrix to store the results which are generated during every iteration. So, the data of every iteration is stored in a row of a matrix.
Therefore, the size of the matrix depends on the size of the loop and thus the user input.
Now, I want to separate each row of this matrix (cl_matrix) and create separate vectors for every row automatically. How would one go on about? I am stuck here...
So far I have:
Angle = [1 7 15];
for i = 1:length(Angle)
%% do some calculations here %%
cl_matrix(i,:) = A.data(:,7);
end
I want to automate this based on the length of Angle:
length(Angle)
cl_1 = cl_matrix(1,:);
cl_7 = cl_matrix(2,:);
cl_15= cl_matrix(3,:);
Thanks!
The only way to dynamically generate in the workspace variables variables whos name is built by aggregating string and numeric values (as in your question) is to use the eval function.
Nevertheless, eval is only one character far from "evil", seductive as it is and dangerous as it is as well.
A possible compromise between directly working with the cl_matrix and generating the set of array cl_1, cl_7 and cl_15 could be creating a structure whos fields are dynamically generated.
You can actually generate a struct whos field are cl_1, cl_7 and cl_15 this way:
cl_struct.(['cl_' num2str(Angle(i))])=cl_matrix(i,:)
(you might notice the field name, e. g. cl_1, is generated in the same way you could generate it by using eval).
Using this approach offers a remarkable advantage with respect to the generation of the arrays by using eval: you can access to the field od the struct (that is to their content) even not knowing their names.
In the following you can find a modified version of your script in which this approach has been implemented.
The script generate two structs:
the first one, cl_struct_same_length is used to store the rows of the cl_matrix
thesecond one, cl_struct_different_length is used to store arrays of different length
In the script there are examples on how to access to the fileds (that is the arrays) to perform some calculations (in the example, to evaluate the mean of each of then).
You can access to the struct fields by using the functions:
getfield to get the values stored in it
fieldnames to get the names (dynamically generated) of the field
Updated script
Angle = [1 7 15];
for i = 1:length(Angle)
% do some calculations here %%
% % % cl_matrix(i,:) = A.data(:,7);
% Populate cl_matrix
cl_matrix(i,:) = randi(10,1,10)*Angle(i);
% Create a struct with dinamic filed names
cl_struct_same_length.(['cl_' num2str(Angle(i))])=cl_matrix(i,:)
cl_struct_different_length.(['cl_' num2str(Angle(i))])=randi(10,1,Angle(i))
end
% Use "fieldnames" to get the names of the dinamically generated struct's field
cl_fields=fieldnames(cl_struct_same_length)
% Loop through the struct's fileds to perform some calculation on the
% stored values
for i=1:length(cl_fields)
cl_means(i)=mean(cl_struct_same_length.(cl_fields{i}))
end
% Assign the value stored in a struct's field to a variable
row_2_of_cl_matrix=getfield(cl_struct_different_length,(['cl_' num2str(Angle(2))]))
Hope this helps.
I am a total beginner in MATLAB and I hope to find some help here. I have some model prediction results for 80 individuals alltogether in one large matrix. I need to extract the data for each individual from the big matrix, assign them in a new variable/matrix, do some extra calculations and then plot certain information as needed.
To do so, I am trying to write a script with a loop function but in a complicated, or maybe more accurately: in a primitive way!
Simplified Example:
My matrix is called: All_Indi_Data .... its dimension is: 600 rows x 21 columns
%Column 1: grouping variable (e.g., code or ID with values 1,2,3,4,5, etc.);
%Column 2: independent var.;
%Column 3: t;
%Column 4: OBS;
%Column 5: PRED;
i= length (All_Indi_Data);
%% First Indi.
q=1; % indicating the ID of the indi for which I want to extract the data
j=1; % variable added to insure writing start from the first row
for r=1:i
if All_Indi_Data (r,1)==q
Indi_1 (j,1:21) = All_Indi_Data (r,1:21)
j=j+1
end
end
%% Second Indi.
q=q+1
j=1
for r=1:i
if All_Indi_Data (r,1)==q
Indi_2 (j,1:21) = All_Indi_Data (r,1:21)
j=j+1
end
end
.
.
.
1) My first question is: can I allocate these data in new variables (Indi_1, Indi_2, ect.) in a more simple way with or without the loop function?!!! I would appreciate your help a lot.
2) Is there any code or any way to plot these selected parts (according to the grouping variable, e.g. data for Indi_1) from the previously mentioned big matrix without wasting a lot of time and space (wto recopying the core part of the code again and again) for the script, and using the loop function?! in other words, I would like to detect - with loop function & the grouping variable- which values are of interest and then to plot them (e.g. data in colum 3 with data from column 4 for each individual, starting from the first to the last)?!
I hope that I described my problem clearly and hope to hear something from the expert guys :) ...
Thanks a lot in advance ..
Try the following code:
for idx=1:80
pos=find(All_Indi_Data(:,1)==idx);
eval(['Indi_' num2str(idx) '=All_Indi_Data(pos,:);']);
end
What I do is: in each iteration, I search for a value of the ID, indicated in the variable idx. Note that I do not use ´i´ as the name of a variable, because Matlab uses it and ´j´ and the imaginary unit for complex numbers and that could cause problems.
Then, using find I search for the position (or positions) of All_Indi_Data in which I can find the information of that individual. Now I have in the variable ´pos´ the indexes of the rows in which there is information for the individual of interest.
Finally, using eval I extract the data for each individual into a variable. Note that eval combined with a loop makes it easy to create lots of variables. I indicate the rows I want to extract with ´pos´ and, as I want all the columns, I use just ´:´ (you could use ´1:21´ too).
With another similar loop you can plot the information you want. For example:
for idx=1:80
eval(['x=Indi_' num2str(idx) ';']);
% Now I have in X the information for this individual
%Plot the columns of x I want
plot(x(:, 3), x(:,4));
pause; %stay here until a press a key
end
I have a bunch of related matrices of different sizes, and would like to be able to incrementally access them. Is there an easy way to create a vector of handles or pointers to these matrices in Matlab? Or is this not the way I am supposed to do it?
For example, here I want to assign to the vector indexed with i, which will be a handle to the matrices of different size.
rows = [1:6];
columns = [10:2:20];
for i=1:6
vector_of_pointers(i) = ones(rows(i),columns(i));
end
In Matlab, there aren't really pointers.
Instead, you can collect the arrays in a cell array, like so
rows = [1:6];
columns = [10:2:20];
for i=1:6
arrayOfArrays{i} = ones(rows(i),columns(i));
end
To access, say, array #3, you write arrayOfArrays{3}, and if you want its second row only, you write arrayOfArrays{3}(2,:).
You can also create your array using ARRAYFUN
arrayOfArrays = arrayfun(#(u,v)ones(u,v),rows,columns,'uniformOutput',false)
I have a system of equations contained in an anonymous equation. Instead of defining all of the equations when i create the function, I would like to add one in each step of a for loop. Is this possible?
I suppose if you have a linear set of equations, you can construct it using a matrix, then you're free to include new operations by adding rows and columns to the matrix and/or its accompanying right hand side vector.
If you're really trying to use anonymous functions, say if your functions are non-linear, then I would suggest you to look into arrays of anonymous functions. For example,
A = cell(3,1); % Preallocate a 3 by 1 cell array
for ii = 1:3
A{ii} = #(x) x^2+ii; % Fill up the array with anonymous functions
end
Now if you check what's contained in cell array 'A',
A = #(x)x^2+ii
#(x)x^2+ii
#(x)x^2+ii
Don't worry about the display of 'ii' instead of the actual number of the loop variable as we gave it earlier, MATLAB has internally replaced them with those values. Changing 'ii' in the current function scope will also not affect their values in 'A' either. Thus,
A{1}(2) = 5, A{2}(2) = 6 and A{3}(2) = 7
If you're not familiar with cell arrays, you can read up on its usage here.
Again, what you're trying to achieve might be different. I hope this works for you.