Could you explain why this matrix read as a scalar/vector when using surf? Also, is reshaping necessary? [duplicate] - matlab

I am attempting to plot 3D surfaces in MATLAB, and I made use of meshgrid, similar to what the MATLAB tutorials said here: http://www.mathworks.com/help/matlab/ref/meshgrid.html
I wrote a very simple three line script that I believed would produce the surface z = x + y and it is as follows:
[x , y] = meshgrid( linspace( 0 , 10 , 10 ) , linspace( 0 , 10 , 10 ) );
z = x + y;
surf( [ x , y , z] );
From what I understand, line 1 produces all combinations of (x,y) coordinates evenly spaced from 0 to 10. Then line 2 just applies the formula z = x + y to that exhaustive list of combinations. Then line 3 just plots all the (x, y, z) points.
But I got the following "thing" as output:
I'm pretty sure the graph in the above picture is not z = x + y, and I have no clue why there aren't two axes going up to maximum value 10.
Still, I find the script too simple and couldn't see anything wrong with it. Could anyone point out where I overlooked something? Thank you.

Your syntax for generating the 3D coordinates is right. Your call to surf is incorrect. What you actually need to do is separate x, y and z into three separate parameters:
surf(x,y,z);
When you do that, you get this surface. Take note that the figure generated was using MATLAB R2013a, so the colour map shown is not the parula colour map that is available as of R2014b and up, but the surface will be the right one that is what you're looking for:
... now why do you need to separate your x, y and z points to create the surface? The reason why is because doing [x,y,z] means that you are concatenating the x, y and z coordinates into a single 2D signal, and so what's happening is that you are creating a 2D signal that is 10 x 30. Calling surf with this single 2D array automatically assumes that the x values span from 1 to 30 and the y values span from 1 to 10 and those are the 2D grid of values that span the axis of your surf plot in conjunction with the z values shown, where the z values originate from the concatenated matrix created earlier. If you look at the plot you generated, you can see the x values are spanning from 1 to 30, and that's obviously not what you want.
You need to separate the x, y and z values to achieve the desired plane.

Related

Incorrect graph when trying to plot z = x + y with MATLAB

I am attempting to plot 3D surfaces in MATLAB, and I made use of meshgrid, similar to what the MATLAB tutorials said here: http://www.mathworks.com/help/matlab/ref/meshgrid.html
I wrote a very simple three line script that I believed would produce the surface z = x + y and it is as follows:
[x , y] = meshgrid( linspace( 0 , 10 , 10 ) , linspace( 0 , 10 , 10 ) );
z = x + y;
surf( [ x , y , z] );
From what I understand, line 1 produces all combinations of (x,y) coordinates evenly spaced from 0 to 10. Then line 2 just applies the formula z = x + y to that exhaustive list of combinations. Then line 3 just plots all the (x, y, z) points.
But I got the following "thing" as output:
I'm pretty sure the graph in the above picture is not z = x + y, and I have no clue why there aren't two axes going up to maximum value 10.
Still, I find the script too simple and couldn't see anything wrong with it. Could anyone point out where I overlooked something? Thank you.
Your syntax for generating the 3D coordinates is right. Your call to surf is incorrect. What you actually need to do is separate x, y and z into three separate parameters:
surf(x,y,z);
When you do that, you get this surface. Take note that the figure generated was using MATLAB R2013a, so the colour map shown is not the parula colour map that is available as of R2014b and up, but the surface will be the right one that is what you're looking for:
... now why do you need to separate your x, y and z points to create the surface? The reason why is because doing [x,y,z] means that you are concatenating the x, y and z coordinates into a single 2D signal, and so what's happening is that you are creating a 2D signal that is 10 x 30. Calling surf with this single 2D array automatically assumes that the x values span from 1 to 30 and the y values span from 1 to 10 and those are the 2D grid of values that span the axis of your surf plot in conjunction with the z values shown, where the z values originate from the concatenated matrix created earlier. If you look at the plot you generated, you can see the x values are spanning from 1 to 30, and that's obviously not what you want.
You need to separate the x, y and z values to achieve the desired plane.

drawing 3d contour plot from 3d vector

I want to draw a contour plot for 3D data.
I have a force in x,y,z directions I want to plot the contour3 for that
the dimensions of the Fx = 21x21X21 same for Fy and Fz
I am finding force = f*vector(x,y,z)
Then
Fx(x,y,z) = force(1)
Fy(x,y,z) = force(2)
Fz(x,y,z) = force(3)
I did the following but it is not working with me ?? why and how can I plot that
FS = sqrt(Fx.^2 + Fy.^2 + Fz.^2);
x = -10:1:10;
[X,Y] = meshgrid(x);
for i=1:length(FS)
for j = 1:length(FS)
for k=1:length(FS)
contour3(X,Y,FS(i,j,k),10)
hold on
end
end
end
This is the error I am getting
Error using contour3 (line 129)
When Z is a vector, X and Y must also be vectors.
Your problem is that FS is not the same shape as X and Y.
Lets illustrate with a simple example:
X=[1 1 1
2 2 2
3 3 3];
Y=[1 2 3
1 2 3
1 2 3];
Z=[ 2 4 5 1 2 5 5 1 2];
Your data is probably something like this. How does Matlab knows which Z entry corresponds to which X,Y position? He doesnt, and thats why he tells you When Z is a vector, X and Y must also be vectors.
You could solve this by doing reshape(FS,size(X,1),size(X,2)) and will probably work in your case, but you need to be careful. In your example, X and Y don't seem programatically related to FS in any way. To have a meaningful contour plot, you need to make sure that FS(ii,jj,k)[ 1 ] corresponds to X(ii,jj), else your contour plot would not make sense.
Generally you'd want to plot the result of FS against the variables your are using to compute it, such as ii, jj or k, however, I dont know how these look like so I will stop my explanation here.
[ 1 ]: DO NOT CALL VARIABLES i and j IN MATLAB!
I'm not sure if this solution is what you want.
Your problem is that contour and contour3 are plots to represent scalar field in 2D objects. Note that ball is 2D object - every single point is defined by angles theta and phi - even it is an object in "space" not in "plane".
For representation of vector fields there is quiver, quiver3, streamslice and streamline functions.
If you want to use contour plot, you have to transform your data from vector field to scalar field. So your data in form F = f(x,y,z) must be transformed to form of H = f(x,y). In that case H is MxN matrix, x and y are Mx1 and Nx1 vectors, respectively. Then contour3(x,y,H) will work resulting in so-called 3D graph.
If you rely on vector field You have to specify 6 vectors/matrices of the same size of corresponding x, y, z coordinates and Fx, Fy, Fz vector values.
In that case quiver3(x,y,z,Fx,Fy,Fz) will work resulting in 6D graph. Use it wisely!
As I comment the Ander's answer, you can use colourspace to get more dimensions, so You can create 5D or, theoretically, 6D, because you have x, y, z coordinates for position and R, G, B coordinates for the values. I'd recommend using static (x,y,R,G,B) for 5D graph and animated (x,y,t,R,G,B) for 6D. Use it wisely!
In the example I show all approaches mentioned above. i chose gravity field and calculate the plane 0.25 units below the centre of gravity.
Assume a force field defined in polar coordinates as F=-r/r^3; F=1/r^2.
Here both x and yare in range of -1;1 and same size N.
F is the MxMx3 matrix where F(ii,jj) is force vector corresponding to x(ii) and y(jj).
Matrix H(ii,jj) is the norm of F(ii,jj) and X, Y and Z are matrices of coordinates.
Last command ensures that F values are in (-1;1) range. The F./2+0.5 moves values of F so they fit into RGB range. The colour meaning will be:
black for (-1,-1,-1),
red for (1,-1,-1),
grey for (0,0,0)
Un-comment the type of plot You want to see. For quiver use resolution of 0.1, for other cases use 0.01.
clear all,close all
% Definition of coordinates
resolution=0.1;
x=-1:resolution:1;
y=x;
z=-.25;
%definition of matrices
F=zeros([max(size(x))*[1 1],3]); % matrix of the force
X=zeros(max(size(x))*[1 1]); % X coordinates for quiver3
Y=X; % Y coordinates for quiver3
Z=X+z; % Z coordinates for quiver3
% Force F in polar coordinates
% F=-1/r^2
% spherical -> cartesian transformation
for ii=1:max(size(x))
for jj=1:max(size(y))
% temporary variables for transformations
xyz=sqrt(x(ii)^2+y(jj)^2+z^2);
xy= sqrt(x(ii)^2+y(jj)^2);
sinarc=sin(acos(z/xyz));
%filling the quiver3 matrices
X(ii,jj)=x(ii);
Y(ii,jj)=y(jj);
F(ii,jj,3)=-z/xyz^2;
if xy~=0 % 0/0 error for x=y=0
F(ii,jj,2)=-y(jj)/xyz/xy*sinarc;
F(ii,jj,1)=-x(ii)/xyz/xy*sinarc;
end
H(ii,jj)=sqrt(F(ii,jj,1)^2+F(ii,jj,2)^2+F(ii,jj,3)^2);
end
end
F=F./max(max(max(F)));
% quiver3(X,Y,Z,F(:,:,1),F(:,:,2),F(:,:,3));
% image(x,y,F./2+0.5),set(gca,'ydir','normal');
% surf(x,y,Z,F./2+.5,'linestyle','none')
% surf(x,y,H,'linestyle','none')
surfc(x,y,H,'linestyle','none')
% contour3(x,y,H,15)

interpolation of 3D surface in matlab

I have 3 dimensional (X-Y-Z) data which includes-
11 Y vectors (100*1 each (range 0:0.01:1)) each is unique and correspond to the same X vector (100*1 (range 0:0.01:1)). Thus, Y can be treated as matrix with dimension 100*11.
Different Y vectors correspond to different Z values on Z axis (11 values of Z ranging from 0 to 1).
e.g. => Every value of Z on Z axis i.e. Z1=0.05 ... Z11=0.95 has different Y vector for the same X vector. Thus it is like: X-Y1-Z1, X-Y2-Z2, X-Y3-Z3...X-Y11-Z11 (Z1 to Z11 are fixed values like 0.05, 0.1 ,..., 0.95 which are repeated equal to the length of X and Y).
I have already plotted this data as 11 discrete contour lines stacked one above other in 3D space using plot3 hold on. But, I want to create surface out of it. I think I can use interpolation using griddata but I didn't understand how to approach this problem. Can anybody help?

Matlab surface plot not giving desired results

I am charting the following data:
a=[...
0.1, 0.7, 0.00284643369242828;...
0.1, 0.71, 0.00284643369242828;...]
such that column 1 never surpasses approximately 10
also such that column 2 goes from .7 to 1.
Column 3 seems ok
When i chart my surface using surf(a) it looks like this:
it appears not to be properly considering what should be x and y.
anything seem weird there?
I think you need to try one of two things: either break out your height column into its own rectangular matrix Z and use surf(Z) to plot each point relative to its location in the matrix (so your x- and y-axes will not be scaled the way you want), or you can put your desired x- and y-coordinates in their own vectors, and plot the matrix Z (defined at every point (xi, yj) for all i in N and j in M where x is N elements long and y is M elements long) with surf(x,y,Z).
x = 0.1:0.1:10; % or whatever increment you need
y = 0.7:0.01:1; % or whatever increment you need
Z = zeros(length(x),length(y); % initialized to the correct size, fill with data
I think you are going to have to regenerate your Z-data so that it is in a rectangular matrix that is (elements in x) by (elements in y) in dimension.
EDIT: You do not need to recreate your data. If you know that you have n unique elements in x and m unique elements in y, then you can use:
X = reshape(data(:,1),m,n);
Y = reshape(data(:,2),m,n);
Z = reshape(data(:,3),m,n);
surf(X,Y,Z);
And that should give you what you are looking for.

Create 2D grid from vector data in Matlab

I am trying to create a 2-D grid from a vector.
So, for example I have:
x = 1:1:10;
z = 2:2:20;
Now, I want to create a grid which has x on both side of the grid cell and z as grid cell value.
I tried doing it as :
[X,Y] = meshgrid(x, x);
newZ = griddata(x, x ,z, X, Y);
But this gives me error:
The underlying triangulation is empty - the points may be
collinear.
Need help solving this.
In a high level, griddata() takes a 2d surface with variable z-value at each point as the first part of the input, and the query points as the second part of the input. To be more specific, when we look into the definition of the function:
vq = griddata(x,y,v,xq,yq)
x and y specifies the range of x and y values, v is like z-value in a plane, and xq and yq together are query points. Here, v (in your case, z) is expected to be a 2d matrix, to be more specific, the size of v is [length(x), length(y)], whereas in your case, you put z as a vector. Matlab generates the warning since the size doesn't match.
For your reference: http://www.mathworks.com/help/matlab/ref/griddata.html?refresh=true