data analysis - 3D plot - Cartesian product of list

Dear all, I have a set of experimental conditions obtained by sweeping 3 parameters A, B, C. For each condition, I have 1 experimental data. The experimental conditions are listed in an order associated with the cartesian product of list of 3 parameters A, B and C, said vector A(1..n), B(1..m), C(1..p). Threfore for any [A(i) B(j) C(k)], I have 1 experimental data located at the index ind=f(i,j,k) in the matrix of cartesian product of list of A,B and C.
With this index, I can get the experimental value M(index,1) for column 1 of my data, for example.
A = [1 2 3]; B = [10 20 30]; C=[100 200 300] ; R is the cartesian product of list of parameters A,B,C and has a length of mxnxp=27 (in this example). It must give this order of row lines of R as : 1 10 100 ; 1 10 200 ; 1 10 300 ; 1 20 100 ; etc... It is worth to notice that meshgrid(A,B,C) does not give row lines listed above but 1 10 100 ; 1 20 100 ; 1 30 100 ; 2 10 100 ; 2 20 100 ; 2 30 100 ; 3 10 100 ; ... this is not what I want.
The ascending index value of R should corresponds to the correct combination of parameters used in the order A then B then C. Therefore the corresponding 'index' of vector M(index,1) corresponds to the row line of R.
Here comes my hurdle for several weeks: I want to display data on 3D graph (using scatter3, plot3, or surf3). I need to define (X,Y,Z,Color).
X can be either A, B or C. Y can be either A, B, or C. Legend Color can be either A, B, or C. Z is the corresponding data located at the index of R. But I need to build up a 2D or 3D vector for Z.
Indeed plot3(A,B,Z,C) is the same than plot3(B,A,Z,C). In case of 3 parameters (A,B,C), the 3D graphs should be displayed as : plot3(A,B,Z,C) , plot3(A,C,Z,B), plot3(B,C,Z,A).
How to build up the matrix Z by picking up the correct index of R in order to display each 3D graphs?
(I am sorry, I spent a long time to synthetise my question, but it helped me to better define my problem. Still, I feel that for readers, it could be not enough clear. I am so sorry for that).
My final goal is to be able to solve this problem for N parameters (N=1 to 5). The data are recorded in a fixed order (A,B,C,...).
I will be more than happy to get any answer, at least before my head will explose ! Sincrely yours Laurent

Answers (1)

I could be totally wrong, but I think it's pretty simple. Just need a loop for your color parameter. Suppose we build plot3(A,B,Z,C).
hold on
for c = 1:size(data,3) % Loop through C elements
z = data(:,:,c);
plot3(A,B,z,C);
... % Add other plot things here.
end
Looping through one of the other parameters would be very similar.
for b = 1:size(data,2);
z = data(:,b,:);
...
end

9 Comments

Dear Bob, thank you for your prompt answer. What you propose looks simple, and that is what I am looking for. Still I have preliminary issues like : 1- how to build the correct cartesian product of list R from A,B,C in this order ? 2- how to associate data(i,j,k) with the index of R ? In other word, what should be the function of i,j,k that gives the corresponding index (row line) of R ? Yours
About the first issue, I found a function called allcomb(A,B,C) that can build the correct cartesian product of list by respecting the order A,B then C. I deeply thanks the author.
out = [length(A)*length(B) length(B) 1];
for i=0:1:length(A)-1
for j=0:1:length(B)-1
for k=1:1:length(C)
indice = i*out(1)+j*out(2)+k*out(3);
z(i+1,j+1,k) = indice;
end
end
end
by using this code, it is possible to get the index of data corresponding to A(i), B(j) and C(j).
So now, I can get the value M(z(i,j,k),1) from my experimental data array for let's say column 20 (it goes from 1 to 20).
M(z(:,1,1),1) gives A as a column vector.
M(z(1,:,1),2) gives B as a row vector,
M(z(1,1,:),3) gives C as 2D vector rather than 1D.
M(z(:,:,:),20) is all the overall data that I want to plot in Z with different colors driven by vector C.
I am not clear I think ... but how to formulate correctly? I think I should come with a random set of data for Z and post an example of simplified code.
This is an example of my code.
clear all
A = [1 2 3]; B = [10 20 30]; C=[100,200,300];
jump = [length(A)*length(B) length(B) 1];
for i = 1:1:length(A)*length(B)*length(C)
val(i,1) = i^2;
end
% not used all_comb = allcomb(A,B,C); % cartesian product of list (A,B,C) % allcomb function can be found here % https://fr.mathworks.com/matlabcentral/fileexchange/10064-allcomb-varargin?s_tid=srchtitle
for i=0:1:length(A)-1
for j=0:1:length(B)-1
for k=1:1:length(C)
indice = i*jump(1)+j*jump(2)+k*jump(3);
z(i+1,j+1,k) = indice;
end
end
end
val(z(:,1,1),1)
val(z(1,:,1),1)
val(z(1,1,:),1)
for i=1:length(C)
plot3(A,B,val(z(:,:,i),1),C) % Vectors must be the same length.
hold on
end
A couple of small things. In your loops you have 0:1:length(A)-1. The :1: here is unnecessary, as it is the default. Also, you have k*jump(3). This can just be k, since jump(3)=1.
I'm a little confused what you're doing here? Are you just trying to put all of the (A,B,C) data into one 2D matrix? I don't understand what the point of this is, since z still ends up being a 3D matrix.
Dear Bob, thanks again for helping me. Yes you are right, jump(3)=1 then I could use only k in this loop. But I am trying to build up a general case. Here there is only 3 parameters sweeping in my experiments, but it might have 3,4 or even 5. In this particular case, the 3rd parameter is swept every 1. It jumps to another value for each experiment. z(i,j,k) is a 3D matrix that output 1 value corresponding to the index of a 1D vector (val) containing the data I want to plot. To build a plot3, I need 1D vector A, 1D vector B, and also C that will be displayed as a legend. Here, I have a problem to build Z correctly, for all values of A, all values of B, with colors of C. I can plot3 but using 3 for loops on i,j and k. In this case, the graph is built point by point, not as a 2D vector. Therefore it is difficult to create surf3 for each colors defined by C. Scatter3 can display the data with 3x 'for' loops, but surf3 is not possible. That is why I think that for each value of C, I should not plot 'val' as point by point but try to build a 2D vector. Still not clear ... maybe.
OK, I will try to simplify as much as I can.
X = (1:1:5)'; % vector of Param 1
Y = (1:1:10)'; % vector of Param 2
Z = sin((1:1:50))'; % vector of data associated with Param 1&2
shape_Z = reshape(Z, length(X), length(Y));% in 2D representation
Now, shape_Z contains the values for each combination of X and Y; How to display (X,Y,Z) on a 3D graph?
Have you tried using mesh()? Basic form is mesh(X,Y,Z) where Z is 2D with [length(Y),length(X)] = size(Z).
I'm still a little unsure why you're remaking Z. I understand that you're trying to reshape it into a 2D vector, but didn't you already have Z as a 3D vector (A,B,C)? If this is the case, than for each C value, Z(:,:,C) is the same thing as what you're creating in shape_Z.
Well, I tried meshgrid, but I could not understand well. Also in your answer, I still don't understand why it is [length(Y) length(X) and not [length(X) length(Y)] which should be more intuitive. But what is working is the following code :
X = (-1:1:5)'; sx = size(X)
Y = (-1:1:10)'; sy = size(Y)
Z = sin((0:1:sx(1)*sy(1)-1))'; size(Z)
shape_Z = reshape(Z, length(X), length(Y)); size(shape_Z)
figure
surf(shape_Z)
alpha 0.5
Still, I cannot understand why it works, but it works. surf(X,Y,shape_Z') works also. So ... nothing very intuitive. Thanks again for your valuable help and suggestions.
Hey, if it works, it works. Understanding is good though.
I used [Y, X] instead of [X, Y] because that is how it is defined by the function, not my personal preference. The same applies for the dimensions of Z used in surf.
surf(Z) plots Z in a 3D surface with X and Y values set as integers for each row and column of Z. surf(X,Y,Z) plots Z in a 3D surface with X and Y values set as corresponding rows and columns of Z. I.e. if X = [1 2 3] and Y = [10 20 30] and you use surf(Z) then Z(1,1) will be plotted at the (x, y) coordinate of (1,1) because no X and Y were specified in surf. But if you use surf(X, Y, Z) then Z(1,1) will be plotted at (1, 10), to properly correspond to the X and Y arrays specified.

Sign in to comment.

Categories

Asked:

on 26 Jul 2018

Commented:

on 31 Jul 2018

Community Treasure Hunt

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

Start Hunting!