How to draw 3D surface plots in Python
A 3D surface plot is usually used for the data with 1 dependent variable and 2 independent variables. It can display the trend, shape and spatial distribution. In this article, I am going to introduce how to use Python code to draw 3D surface plots.
Let’s see a basic one first:
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
x = np.linspace(-5, 5, 100)
y = np.linspace(-5, 5, 100)
X, Y = np.meshgrid(x, y)
Z = np.sin(np.sqrt(X**2 + Y**2))
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.plot_surface(X, Y, Z, cmap='viridis')
ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_zlabel('Z')
ax.set_title('3D Surface Plot')
plt.show()
Assuming that we have some sales data. It contains prices and sales. We can use a 3D surface plot to visual the data to display the relationship of prices and sales:
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
# Price
prices = np.array([10, 20, 30, 40, 50, 60, 70, 80])
# Sales
sales = np.array([100, 150, 200, 250, 300, 350, 400, 450])
price, sale = np.meshgrid(prices, sales)
# Performance
performance = np.array([
[1000, 1200, 1400, 1600, 1800, 2000, 2200, 2400],
[1200, 1400, 1600, 1800, 2000, 2200, 2400, 2600],
[1400, 1600, 1800, 2000, 2200, 2400, 2600, 2800],
[1600, 1800, 2000, 2200, 2400, 2600, 2800, 3000],
[1800, 2000, 2200, 2400, 2600, 2800, 3000, 3200],
[2000, 2200, 2400, 2600, 2800, 3000, 3200, 3400],
[2200, 2400, 2600, 2800, 3000, 3200, 3400, 3600],
[2400, 2600, 2800, 3000, 3200, 3400, 3600, 3800]
])
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.plot_surface(price, sale, performance, cmap='coolwarm')
ax.set_xlabel('Price')
ax.set_ylabel('Sales')
ax.set_zlabel('Performance')
ax.set_title('Sales Performance with Price and Sales')
plt.show()
Here performance is a 2D array. Every cell of it means a performance with corresponding price and sales. In this case, higher surface means higher performance. So we can find a best price-sales point.
Sometimes, we may need multiple plots displaying in the mean time:
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
x = np.linspace(-5, 5, 100)
y = np.linspace(-5, 5, 100)
X, Y = np.meshgrid(x, y)
Z1 = np.sin(np.sqrt(X**2 + Y**2))
Z2 = np.cos(X) * np.sin(Y)
Z3 = np.exp(-(X**2 + Y**2)/10) * np.cos(np.sqrt(X**2 + Y**2))
fig = plt.figure()
# plog 1
ax1 = fig.add_subplot(131, projection='3d')
ax1.plot_surface(X, Y, Z1, cmap='viridis')
ax1.set_xlabel('X')
ax1.set_ylabel('Y')
ax1.set_zlabel('Z1')
# plog 2
ax2 = fig.add_subplot(132, projection='3d')
ax2.plot_surface(X, Y, Z2, cmap='plasma')
ax2.set_xlabel('X')
ax2.set_ylabel('Y')
ax2.set_zlabel('Z2')
# plot 3
ax3 = fig.add_subplot(133, projection='3d')
ax3.plot_surface(X, Y, Z3, cmap='magma')
ax3.set_xlabel('X')
ax3.set_ylabel('Y')
ax3.set_zlabel('Z3')
fig.suptitle('Multiple 3D Surface Plots')
fig.tight_layout()
plt.show()
Like 2D plots, use “add_subplot” to create a 1*3 figure here. Then draw the plot for specific position. “tight_layout()” is able to make the whole figure more visible.
Thank you for reading.
