Foundations of computer programming in MATLAB — 3D plotting

Sometimes we would like to visually represent data or functions three-dimensionally. MATLAB has several built-in functions for generating such graphics, and we will explore a number of them. As with 2D plotting, we must first create a figure.

The surf function

The surf function creates a three-dimensional shaded surface in a figure. It typically accepts three arguments: x, y, and z. The first two can be ranges of x- and y-values or meshgrid arrays. Before we unpack what the command meshgrid does, let’s look at an example.

x = -1:.02:1;                  % array of x values
y = -1:.02:1;                  % array of y values
[X,Y] = meshgrid(x,y);     % grid of x and y values
Z=sin(5*(X.^2+Y.^2));        % function we're plotting
figure;
surf(X,Y,Z);

This creates a new figure (unnamed) and plots the function \(f(x,y) = \sin{\left(5\left(x^2 + y^2\right)\right)}\) over the intervals $x \in [-1,1]$ and $y \in [-1,1]$.

When we specified x and y, we were choosing the mesh spacing in the $x$- and $y$-directions. Let n = length(x) and m = length(y). Since $f(x,y)$, which we’re plotting on the $z$-axis, is a function of $x$ and $y$, we must somehow construct an n by m matrix of $z$-values. We could do this with a for loop, for instance. However, “vector” operations are much more efficient and easier to write. For this reason, we use meshgrid to construct a two-dimensional array of m copies of x, which gives the n by m array X. Similarly, meshgrid constructs another two-dimensional array of n copies of y, which gives the n by m array Y.

This gives us the ability to simply do element-wise operations to obtain Z. The surf function can be written as above or it can be written surf(x,y,Z).

Labeling and formatting

Many of the commands available in two-dimensional plots are still available and are extended in the obvious ways. For instance, we can label the previous example.

x = -1:.02:1;                  % array of x values
y = -1:.02:1;                  % array of y values
[X,Y] = meshgrid(x,y);     % grid of x and y values
Z=sin(5*(X.^2+Y.^2));        % function we're plotting
figure;
surf(X,Y,Z);
xlabel('x');
ylabel('y');
zlabel('z');
title('ripple')

Another colormap can be substituted for the default. Immediately after the last example, use the command

colormap(bone);

Also try colormap(hot). Here are a few others: hsv, cool, summer, and gray.

A colorbar gives the scale of the coloring. Simply call the colorbar command after surf.

Sometimes we don’t want to see the mesh lines. We can turn them off and interpolate the face shading for a nice, sexy surface.

x = -1:.02:1;                  % array of x values
y = -1:.02:1;                  % array of y values
[X,Y] = meshgrid(x,y);     % grid of x and y values
Z=sin(5*(X.^2+Y.^2));        % function we're plotting
figure;
h = surf(X,Y,Z);
set(h,'edgecolor','none')
shading interp

Exercises

  1. Plot a 3D surface of the function $f(x,y) = x^2 - y^2$. Label each axis and entitle the plot.
  2. On the same axes, plot the functions $f(x,y) = x^2 - y^2$ and $f(x,y) = y^2 - x^2$. Use colormap hsv.
  3. Create a surface plot named h of the function \(f(x,y) = \frac{\sin{\sqrt{x^2 + y^2}}}{\sqrt{x^2 + y^2}}\) with the colormap hot over the intervals $x \in [-20,20]$ and $y \in [-20,20]$. Use the following magic (source) to make it come alive. <pre>view(0,75) shading interp lightangle(-45,30) h.FaceLighting = 'gouraud'; h.AmbientStrength = 0.3; h.DiffuseStrength = 0.8; h.SpecularStrength = 0.9; h.SpecularExponent = 25; h.BackFaceLighting = 'unlit';</pre>
  4. With the previous example, make the surface have a $75 \%$ opacity ($25 \%$ transparency).
  5. With the previous example, plot only those values that lie inside the circle $x^2 + y^2 = 20^2$.