I'm trying to use matlab to create a surface plot of a function that has a limited domain [it's a square root, and the argument goes negative].
x = [-2:0.02:4]
y = [-6:0.1:6]
[X,Y] = meshgrid(x,y)
If I do
surf(X,Y,sqrt(9-(X-1).*(X-1)-Y.*Y/4))
I get an error message because the function is imaginary outside of an ellipse. So I could do
surf(X,Y,real(sqrt(9-(X-1).*(X-1)-Y.*Y/4)))
But then it's 0 outside of the domain. Really I'd like it to just not plot anything at all.
The only idea I have is to modify Y
so that for each X
, it's limited to the values where the function is defined. But I'd really like a way to say 'just don't plot those parts' so that I don't have to calculate the domain each time.
Exploiting the fact that NaNs are usually ignored by graphical routines, you could use:
x = [-2:0.02:4];
y = [-6:0.1:6];
[X,Y] = meshgrid(x,y);
clear x y;
W=sqrt(9-(X-1).*(X-1)-Y.*Y/4);
Z=nan(size(W));
W_isreal=abs(imag(W))<=eps();
Z(W_isreal)=real(W(W_isreal));
clear W W_isreal;
surf(X,Y,Z);
Notice that this approach introduces unsightly artifacts near z=0:
A more elegant approach that avoids such gaps near z=0 could be:
[X,Y,Z]=ellipsoid(1,0,0,3,6,3);
surf(X,Y,Z);
zlim([0 Inf]);
% Verify computations
W=9-(X-1).*(X-1)-Y.*Y/4;
W_istruenegative=(W<=-1e-6);
if any(W_istruenegative(:))
error('Our ellipsoid looks invalid.');
end
if any( abs(sqrt(abs(W(:))) - abs(Z(:))) > 1e-6 ) %verify ellipsoid
error('Our ellipsoid looks invalid.');
end
clear W W_istruenegative;