-
Basics Review 1
-
Lecture1.1
-
-
Subplots 2
-
Lecture2.1
-
Lecture2.2
-
-
3D Plots 2
-
Lecture3.1
-
Lecture3.2
-
-
Animation 1
-
Lecture4.1
-
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)
[[ 0 1 2 3 4 5 6 7 8 9 10]
[ 0 1 2 3 4 5 6 7 8 9 10]
[ 0 1 2 3 4 5 6 7 8 9 10]
[ 0 1 2 3 4 5 6 7 8 9 10]
[ 0 1 2 3 4 5 6 7 8 9 10]
[ 0 1 2 3 4 5 6 7 8 9 10]
[ 0 1 2 3 4 5 6 7 8 9 10]
[ 0 1 2 3 4 5 6 7 8 9 10]
[ 0 1 2 3 4 5 6 7 8 9 10]
[ 0 1 2 3 4 5 6 7 8 9 10]
[ 0 1 2 3 4 5 6 7 8 9 10]]
[[ 0 0 0 0 0 0 0 0 0 0 0]
[ 1 1 1 1 1 1 1 1 1 1 1]
[ 2 2 2 2 2 2 2 2 2 2 2]
[ 3 3 3 3 3 3 3 3 3 3 3]
[ 4 4 4 4 4 4 4 4 4 4 4]
[ 5 5 5 5 5 5 5 5 5 5 5]
[ 6 6 6 6 6 6 6 6 6 6 6]
[ 7 7 7 7 7 7 7 7 7 7 7]
[ 8 8 8 8 8 8 8 8 8 8 8]
[ 9 9 9 9 9 9 9 9 9 9 9]
[10 10 10 10 10 10 10 10 10 10 10]]
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)
[[98 85 74 65 58 53 50 49 50 53 58]
[85 72 61 52 45 40 37 36 37 40 45]
[74 61 50 41 34 29 26 25 26 29 34]
[65 52 41 32 25 20 17 16 17 20 25]
[58 45 34 25 18 13 10 9 10 13 18]
[53 40 29 20 13 8 5 4 5 8 13]
[50 37 26 17 10 5 2 1 2 5 10]
[49 36 25 16 9 4 1 0 1 4 9]
[50 37 26 17 10 5 2 1 2 5 10]
[53 40 29 20 13 8 5 4 5 8 13]
[58 45 34 25 18 13 10 9 10 13 18]]
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()
[[14 13 12 11 10 9 8 7 8 9 10]
[13 12 11 10 9 8 7 6 7 8 9]
[12 11 10 9 8 7 6 5 6 7 8]
[11 10 9 8 7 6 5 4 5 6 7]
[10 9 8 7 6 5 4 3 4 5 6]
[ 9 8 7 6 5 4 3 2 3 4 5]
[ 8 7 6 5 4 3 2 1 2 3 4]
[ 7 6 5 4 3 2 1 0 1 2 3]
[ 8 7 6 5 4 3 2 1 2 3 4]
[ 9 8 7 6 5 4 3 2 3 4 5]
[10 9 8 7 6 5 4 3 4 5 6]]
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()