Does surf() Behave as Expected with ndgrid() Inputs?

4 views (last 30 days)
Define a function
clear
f = @(x,y) x;
Case 1: square mesh, meshgrid, vector inputs to surf
x = 0:5;
y = 100:105;
[Xmesh,Ymesh] = meshgrid(x,y);
Zmesh = f(Xmesh,Ymesh);
figure
surf(x,y,Zmesh)
xlabel('x');ylabel('y')
Case 2: square mesh, ndgrid, vector inputs to surf
[Xnd,Ynd] = ndgrid(x,y);
Znd = f(Xnd,Ynd);
figure
surf(x,y,Znd)
xlabel('x');ylabel('y')
Cases 1 and 2 clearly indicate that the third input to surf should be built in meshgrid format consistent with the examples in the documentation.
What happens if using array inputs to surf?
Case 3: square mesh, meshgrid, array inputs to surf
figure
surf(Xmesh,Ymesh,Zmesh)
xlabel('x');ylabel('y')
Same result as Case 1, as expected
Case 4: square mesh, ndgrid, array inputs to surf
figure
surf(Xnd,Ynd,Znd)
xlabel('x');ylabel('y')
Why isn't Case 4 the same as Case 2?

Accepted Answer

Voss
Voss on 6 Jun 2022
"Why isn't Case 4 the same as Case 2?"
Because Case 2 is erroneous. For vectors X and Y input to surf, matrix Z must be of size numel(Y)-by-numel(X).
Case 2 produces a surface because x and y happen to be the same length, but consider what happens when vectors x and y aren't the same length:
f = @(x,y) x;
x = 0:6;
y = 100:105;
[Xnd,Ynd] = ndgrid(x,y);
Znd = f(Xnd,Ynd);
% Case 2: square mesh, ndgrid, vector inputs to surf
figure
try
surf(x,y,Znd) % Znd is numel(x)-by-numel(y)
catch ME
disp(ME.message);
end
Data dimensions must agree.
xlabel('x');ylabel('y')
% Case 2a (corrected): square mesh, ndgrid, vector inputs to surf
figure
surf(x,y,Znd.') % Znd.' is numel(y)-by-numel(x)
xlabel('x');ylabel('y')
% Case 4: square mesh, ndgrid, array inputs to surf
figure
surf(Xnd,Ynd,Znd)
xlabel('x');ylabel('y')
  5 Comments
Voss
Voss on 6 Jun 2022
Edited: Voss on 6 Jun 2022
"if using x,y vector inputs, then Z must be in meshgrid format"
I think that's a good way to put it.
"if using X,Y matrix inputs, then X/Y/Z can be in either meshgrid or ndgrid format"
Yes, or any other format.
X and Y need not represent points on a rectangular grid at all, e.g.:
r = linspace(0.5,2.5,5).';
th = linspace(0,2*pi,9);
X = r.*cos(th)
X = 5×9
0.5000 0.3536 0.0000 -0.3536 -0.5000 -0.3536 -0.0000 0.3536 0.5000 1.0000 0.7071 0.0000 -0.7071 -1.0000 -0.7071 -0.0000 0.7071 1.0000 1.5000 1.0607 0.0000 -1.0607 -1.5000 -1.0607 -0.0000 1.0607 1.5000 2.0000 1.4142 0.0000 -1.4142 -2.0000 -1.4142 -0.0000 1.4142 2.0000 2.5000 1.7678 0.0000 -1.7678 -2.5000 -1.7678 -0.0000 1.7678 2.5000
Y = r.*sin(th)
Y = 5×9
0 0.3536 0.5000 0.3536 0.0000 -0.3536 -0.5000 -0.3536 -0.0000 0 0.7071 1.0000 0.7071 0.0000 -0.7071 -1.0000 -0.7071 -0.0000 0 1.0607 1.5000 1.0607 0.0000 -1.0607 -1.5000 -1.0607 -0.0000 0 1.4142 2.0000 1.4142 0.0000 -1.4142 -2.0000 -1.4142 -0.0000 0 1.7678 2.5000 1.7678 0.0000 -1.7678 -2.5000 -1.7678 -0.0000
Z = r.*sqrt(th);
surf(X,Y,Z,'FaceColor','interp')
view([-115 65])
copyobj(gca(),figure())
view(2)
Paul
Paul on 6 Jun 2022
Interesting, all of the examples in the doc use a rectangular grid.

Sign in to comment.

More Answers (0)

Categories

Find more on Graphics Performance in Help Center and File Exchange

Products


Release

R2022a

Community Treasure Hunt

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

Start Hunting!