I want to interpolate an irregular 3-D grids using matlab command "interp3", what I
have is the coordinates of X,Y,Z and the values at each point. The dimension of x,y,z is 76*36*16 and the sampling positions stored in vectors x, y, and z are increasing.
x
y
z
the values at each point
the commands I use to interpolate the grids are as belows:
[x_out,y_out,z_out]=meshgrid(-310:5:310,-165:5:205,-70:5:5);
vel_grid=interp3(x_3d,y_3d,z_3d,vel,x_out,y_out,z_out);
and the error message:
your input grid is invalid Meshgrid.
I can't figure where is wrong about my input grids, the sampling positions stored in vectors x, y, and z are increasing. What conditions should my input grids still satisfy?
Since your 3-D grids are irregular you cannot use interp3 which supposes that your initial data is in a proper meshgrid order.
for example
x = rand(76,36,16);
y = rand(76,36,16);
z = rand(76,36,16);
v = rand(76,36,16);
slice(x,y,z,v,0,0,0);
will result in
Error using interp3 (line 147)
Input grid is not a valid MESHGRID.
Error in slice (line 104)
vi = interp3(x,y,z,v,xi,yi,zi,method);
However you can use scatteredInterpolant as such
F =scatteredInterpolant(x_3d(:),y_3d(:),z_3d(:),vel(:));
[x_out,y_out,z_out]=meshgrid(-310:5:310,-165:5:205,-70:5:5);
v_out = F(x_out,y_out,z_out);
xslice = [0];
yslice = [0];
zslice = [,0];
slice(x_out,y_out,z_out,vel(:),xslice,yslice,zslice)
Related
I would like to achieve a 3D surface plot. My outputs are as follows.
For a particular value of z, I get y for each value of x (x ranges like 0:0.1:1.4).
Then I vary z and, for the same range of x, I get y values.
The result can be visualised as 2D plots at discrete z values, consisting of the range of x and its corresponding y. Here is my original plot:
I would like to create a 3D surface plot instead, like a blanket wrapped over the above 2D plots.
Here's an example for the two types of plots:
figure
hold on
grid on
view(30,40)
x = 0:.01:4;
z = .3:.3:3;
y = NaN(numel(x), numel(z));
for k = 1:numel(z)
y(:,k) = abs((4-x).*sin(x/(1+z(k)))); % compute a vector as function output
% for input vector x, for each z. Store as a column in matrix y
plot3(x,repmat(z(k),size(x)),y(:,k)) % plot in 3D space
end
figure
surf(x,z,y.','edgecolor','none') % surface plot
view(30,40)
grid on
I have done calculations with 2 different methods. For those calculations I have varied 2 parameters: x and y
In the end, I have calculated the % ERROR between both methods, for each variation.
Now I want to create a 3D surface plot from the results:
x -> on x axis
y -> on y axis
Error -> on z axis
Here is a sample of the data:
A = [
-0.1111 1.267 9.45680081826912
-0.1111 2.6 212.361735695025
-0.25 1.533 40.5729362609655
-0.25 2.867 601.253624894196
-0.4286 1 0.12116749607863
-0.4286 3.4 79.6948438921078
-0.6667 2.067 33.3495544017519
-0.6667 3.667 141.774875517481
-1 2.6 -0.0399171449531781
0.09091 1.533 163.7083541414 ];
But, when I try to plot it with surf function:
x = A(:,1);
y = A(:,2);
z = A(:,3);
surf(x,y,z)
, I get an error:
Error using surf (line 75)
Z must be a matrix, not a scalar or vector
Error in ddd (line 27)
surf(x,y,z)
Can you help me with a code that can restructure the data in the format acceptable for the surf function?
P.S. - I am currently trying to write some sample code with my first attempts. I will post it as soon as I get to somewhere.
The surf function needs a grid of X,Y-values as input. Your data however is simply three vectors with some combinations, not a full grid. As described in the documentation, the meshgrid function is often helpful to create such grid matrices. Use the unique function to select all unique values in x and y and create matrices of all possible combinations:
[X,Y] = meshgrid(unique(x),unique(y));
To create a Z matrix which fits the [X,Y] grid, the griddata function is helpful:
Z = griddata(x,y,z,X,Y);
Now you can call surf with the grid matrices as input:
surf(X,Y,Z);
create the grid for the first and second column and calculate Z using your formula.
help meshgrid in MATLAB
I have a data file from a physics model that shows the density of a certain material around a object. The data file is in spherical coordinates and is reshaped to its original dimensions (Theta,Phi,R and density). Sph2cart is used to transform from spherical coordinates to cartesian (x,y,z) coordinates. To visualize the different densities around the object I found the isosurface function in MATLAB (example: http://www.mathworks.com/matlabcentral/answers/110977-3d-density-plot-multiple-isosurfaces-on-the-same-plot).
This is the code that I currently have:
input = importdata( 'denNa20.dat' );
input(1,:)=[];
theta = reshape(input(:,3),200,20,40);
phi = reshape(pi/2 - input(:,2),200,20,40);
r = reshape(input(:,1),200,20,40);
density = reshape(input(:,4),200,20,40);
[x,y,z] = sph2cart(theta,phi,r);
% This has ofcourse the complete wrong dimensions but then it works
% [x,y,z] = meshgrid(1:1:20,1:1:200,1:1:40);
p = patch(isosurface(y,x,z,density,0.00001));
isonormals(x,y,z,density,p);
set(p,'FaceColor','red','EdgeColor','none','FaceAlpha',0.15);
daspect([1 1 1])
view(3)
grid on
camlight; lighting phong
When I run the code I receive the following errors:
Error using interp3 (line 146)
Input grid is not a valid MESHGRID.
Error in isonormals (line 75)
n(:,1)=interp3(x, y, z, nx, verts(:,1), verts(:,2), verts(:,3));
Error in data_import_plot (line 16)
isonormals(x,y,z,density,p);
If I create my own meshgrid with very easy x,y,z coordinates (check % in code) it works. I don't know what I am doing wrong. I hope some one can help me.
Cheers,
Jeroen
P.S. if you want you can download the data file from this link https://www.dropbox.com/s/msphgmg2oyi91cx/denNa20.dat?dl=0
I found out that the problem was that isosurface does not accept irregular x,y and z coordinates. This is what I found to be the solution. I used scatteredInterpolant to interpolate the density and then created my own meshgrid.
input = importdata( 'denNa20.dat' );
input(1,:)=[];
[x,y,z] = sph2cart(input(:,3),pi/2 - input(:,2),input(:,1));
density = input(:,4);
F = scatteredInterpolant(x,y,z,density);
xRange = linspace(min(x),max(x),75);
yRange = linspace(min(y),max(y),75);
zRange = linspace(min(z),max(z),75);
[x,y,z] = meshgrid(xRange,yRange,zRange);
density = F(x,y,z);
axis([-5000,5000,-5000,5000,-5000,5000])
p = patch(isosurface(x,y,z,density,0.00001));
isonormals(x,y,z,density,p);
set(p,'FaceColor','red','EdgeColor','none','FaceAlpha',0.50);
daspect([1 1 1])
view(3)
grid on
camlight; lighting phong
I have an Nx2 input matrix called X. I also have the output values Y which is a vector Nx1. I create some data to test as follows:
Xtest=linspace(x_min,x_max,n);
Ytest=linspace(y_min,y_max,n);
So, matrix Z is of nx2 dimensions and is going to be used as my test points. I use the default tuning of the parameters found in the demo provided with the GPML lib which is as follows:
covfunc = {#covMaterniso, 3};
ell = 1/4; sf = 1;
hyp.cov = log([ell; sf]);
likfunc = #likGauss;
sn = 0.1;
hyp.lik = log(sn);
and then use the gp function:
[ymu ys2 fmu fs2] = gp(hyp, #infExact, [], covfunc, likfunc, x, y, z);
I expected ymu to be the predicted value for each testing value in z. When I plot this like this:
[L1,L2]=meshgrid(Xtest',Ytest');
[mu,~]=meshgrid(ymu,ymu);
surf(L1,L2,ymu);
I get a strange surface. i.e i get stripes of coloured area rather some Gaussian like structure which is expected. The data in X and Y are real life data.
What I would expect:
You're using it wrong. Your z variable should be given by [L1(:),L2(:)]. Then what you should plot is:
surf(L1,L2,reshape(ymu,size(L1)));
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