3D Surface Plots
3D Surface Plots¶
Sometimes, we want to actually plot a surface instead of a line. To achieve this, we are going to need to use X, Y and Z in matrix form. First, let’s see how to turn 1D X values and 1D Y values into matrices. Let’s say that our x values are 1-10 and are y-values are 1-10 as well. By using numpy’s meshgrid function, we are able to essentially get all combinations of these values easily returned as a matrix. In this sense, we will have a 10×10 X matrix and 10×10 Y matrix. Run the code below, and you should see from the output what I mean.
#Mesh grid takes 1D arrays of X and Y and combines them into matrices like below for the combinations
X = list(range(0,11))
Y = list(range(0,11))
X,Y = np.meshgrid(X, Y)
print(X)
print()
print(Y)
Now that we have X and Y, let’s say we want to find the squared residual (difference) for each point X and Y, and sum the squared residuals found from this. The equation then is simply $(X-7)^2 + (Y-7)^2$. The code below creates this Z matrix.
#Simple equation for sum of squared residuals from point 7,7
Z = (X - 7) ** 2 + (Y - 7) ** 2
print(Z)
For plotting the surface, one option is to use ax.plot_wireframe() with the X, Y and Z variables. This creates a wireframe plot.
#Wireframe plots the 2D matrices of X, Y, Z
fig = plt.figure(figsize=(12,12))
ax = fig.add_subplot(111, projection='3d')
ax.plot_wireframe(X,Y,Z)
plt.show()
The plot_surface() function does a similar thing, except it is a filled in surface. As well, we can pass a colormap (in this case I chose to use the classic coolwarm colormap).
from matplotlib import cm
#Plot surface is similar except you can also add in a colormap
fig = plt.figure(figsize=(12,12))
ax = fig.add_subplot(111, projection='3d')
ax.plot_surface(X,Y,Z, cmap=cm.coolwarm)
plt.show()
We can compare this function of z which is simply the summed absolute value differences, meaning |X-7| + |Y-7|. This gives a linear shape which can be seen from the graph.
#Compare with using the sum of absolute distance on X+Y
Z = abs(X - 7) + abs(Y - 7)
print(Z)
#Plot
fig = plt.figure(figsize=(12,12))
ax = fig.add_subplot(111, projection='3d')
ax.plot_surface(X,Y,Z, cmap=cm.coolwarm)
plt.show()
Finally, if you call %matplotlib notebook, you will be able to make the graph more interactive. You can try dragging it to move it around!
#If you call %matplotlib notebook you will be able to actually interact and drag the plot around
%matplotlib notebook
fig = plt.figure(figsize=(6,6))
ax = fig.add_subplot(111, projection='3d')
ax.plot_surface(X,Y,Z, cmap=cm.coolwarm)
plt.show()