We also have the ability to add contours to a 3D plot. Try the following code:
# Contour plot (filled/unfilled)
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
x,y = np.meshgrid(np.arange(-10,10,0.5), np.arange(-10,10,0.5))
r = np.linalg.norm([x,y], axis=0)
goldstone = -200*np.power(r,2)+np.power(r,4)
ax.contour(x,y,goldstone)
From this code, we get a nice set of contours in 3D, as shown here:
By adding the letter f ahead of contour, we get 3D filled contours, as shown here:
Hence, we see that, in general, most of these methods are very similar to the 2D version of our plot, but with a few extra keyword arguments on top. contour has a couple of really neat keyword arguments that are particularly useful, as well.
So, from the preceding output, we see that the code generates contours in the z direction; in other words, it is finding values of equal z height:
- In order to find values of x, we pass the zdir keyword argument:
# Contour plot: zdir, offset
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
x,y = np.meshgrid(np.arange(-10,10,0.5), np.arange(-10,10,0.5))
r = np.linalg.norm([x,y], axis=0)
goldstone = -200*np.power(r,2)+np.power(r,4)
ax.contour(x,y,goldstone, zdir='x')
The following output shows the resulting plot of the contours in the x dimension:
- Similarly, if we change the value of zdir to y, we will get the following:
- By passing an extra keyword argument called offset, we gain the ability to collapse this contour into one dimension. Hence, it turns a 3D plot into a 2D plot, and places it as a slice in the cube that you have in this volume. By setting offset to 10, it projects those contours onto the wall of the plot as shown:
# Contour plot: zdir, offset
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
x,y = np.meshgrid(np.arange(-10,10,0.5), np.arange(-10,10,0.5))
r = np.linalg.norm([x,y], axis=0)
goldstone = -200*np.power(r,2)+np.power(r,4)
ax.contour(x,y,goldstone, zdir='y', offset=10)
ax.contour(x,y,goldstone, zdir='x', offset=-10)
The output looks as follows:
- However, we notice that the ground surface at the bottom of the cube is empty. So, by setting zdir= 'z', and giving an offset of -10000 (which is where this ground surface is), we see all of the contours projected down, as shown in the following output:
- To place the 3D plot within the volume, we combine 2D and 3D to get a rich representation of multi-dimensional data using the following code:
ax.contour(x,y,goldstone, zdir='z', offset=-10000)
ax.scatter(x,y,goldstone, c=goldstone, cmap='inferno')
Hence, here we have a quite remarkably rich combination of data. We have the color and then the projection of the contours onto three walls of this cube, as shown here:
So, with the 3D axis, we can build incredibly rich visualizations out of high dimensional data sets.