“This is the third day of my participation in the Gwen Challenge in November. Check out the details: The last Gwen Challenge in 2021.”
preface
Matplotlib is Python’s drawing library, which provides a full set of matlab-like command apis to generate the publish-quality graphics you need. The API for creating 3D graphics is very similar to the 2D API. We’ve already learned how to draw a series of 2D charts, and adding another dimension to the chart shows more information. Also, 3D graphics can attract more attention during regular presentations or presentations. In this article, we will explore the use of Matplotlib to plot 3d statistics.
3 d scatter plot
The drawing method of 3D scatter chart is basically the same as that of 2D scatter chart.
import numpy as np
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
# Data generation
a, b, c = 10..28..8. / 3.
def lorenz_map(x, dt = 1e-2) :
x_dt = np.array([a * (x[1] - x[0]), x[0] * (b - x[2]) - x[1], x[0] * x[1] - c * x[2]])
return x + dt * x_dt
points = np.zeros((2000.3))
x = np.array([1... 0.. 0])
for i in range(points.shape[0]):
points[i], x = x, lorenz_map(x)
# draw
fig = plt.figure()
ax = fig.gca(projection = '3d')
ax.set_xlabel('X axis')
ax.set_ylabel('Y axis')
ax.set_zlabel('Z axis')
ax.set_title(Lorenz Attractor A =%0.2f b=%0.2f c=%0.2f' % (a, b, c))
ax.scatter(points[:, 0], points[:, 1],points[:, 2], zdir = 'z', c = 'c')
plt.show()
Copy the code
Tips: Hold down the left mouse button to move the mouse to rotate to view the 3D graphics will rotate.
To use Matplotlib for 3d operations, we first need to import the 3D extension of Matplotlib:
from mpl_toolkits.mplot3d import Axes3D
Copy the code
For 3d drawing, we need to create a Figure instance and attach an Axes3D instance:
fig = plt.figure()
ax = fig.gca(projection='3d')
Copy the code
After that, the 3d scatter plot is drawn in exactly the same way as the 2D scatter plot:
ax.scatter(points[:, 0], points[:, 1],points[:, 2], zdir = 'z', c = 'c')
Copy the code
Tips: Call scatter() of Axes3D instances instead of scatter in PLT. Only the Scatter () method in Axes3D can interpret the 3D data. Annotations in 2D graphs can also be used in 3D graphs, such as set_title(), set_xlabel(), set_ylabel(), and set_zlabel().
You can also change the shape and color of scatter by using the optional parameters of axes3d.scatter () :
ax.scatter(points[:, 0], points[:, 1],points[:, 2], zdir = 'z', c = 'c', marker='s', edgecolor='0.5', facecolor='m')
Copy the code
3 d graph
Similar to plotting a scatter plot in 3D space, plotting a 3D graph also requires setting up an Axes3D instance and calling its plot() method:
Construct the data set
a, b, c = 10..28..8. / 3.
def lorenz_map(x, dt = 1e-2) :
x_dt = np.array([a * (x[1] - x[0]), x[0] * (b - x[2]) - x[1], x[0] * x[1] - c * x[2]])
return x + dt * x_dt
points = np.zeros((8000.3))
x = np.array([1... 0.. 0])
for i in range(points.shape[0]):
points[i], x = x, lorenz_map(x)
# Plotting
fig = plt.figure()
ax = fig.gca(projection = '3d')
ax.plot(points[:, 0], points[:, 1], points[:, 2], c = 'c')
plt.show()
Copy the code
3 d scalar field
The 3D drawing we have seen so far is similar to the corresponding 2D drawing, but also has many unique 3D drawing functions, such as drawing a two-dimensional scalar field as a 3D surface:
x = np.linspace(-3.3.256)
y = np.linspace(-3.3.256)
x_grid, y_grid = np.meshgrid(x, y)
z = np.sinc(np.sqrt(x_grid ** 2 + y_grid ** 2))
fig = plt.figure()
ax = fig.gca(projection = '3d')
ax.plot_surface(x_grid, y_grid, z, cmap=cm.viridis)
plt.show()
Copy the code
Tips: The plot_surface() method uses x, y, and z to display a scalar field as a three-dimensional surface.
If you do not want to see the color of the curve displayed on the 3d surface, you can use plot_surface() to append an optional parameter:
ax.plot_surface(x_grid, y_grid, z, cmap=cm.viridis, linewidth=0, antialiased=False)
Copy the code
Similarly, we can keep only the curve colors and leave the surface colors alone. This can also be done with the optional parameter plot_surface() :
x = np.linspace(-3.3.256)
y = np.linspace(-3.3.256)
x_grid, y_grid = np.meshgrid(x, y)
z = np.sinc(np.sqrt(x_grid ** 2 + y_grid ** 2))
fig = plt.figure()
ax = fig.gca(projection = '3d')
ax.plot_surface(x_grid, y_grid, z, edgecolor='b',color='w')
plt.show()
Copy the code
If we want to eliminate the surface and draw with a wireframe only, we can do this using the plot_wireframe() function:
ax.plot_wireframe(x_grid, y_grid, z, cstride=10, rstride=10,color='c')
Copy the code
The plot_wireframe() parameter is the same as plot_surface(), using two optional parameters, rstride and cstride, to cause Matplotlib to skip a specified number of coordinates on the X and y axes to reduce the density of the curve.
Draw 3D surfaces
In the previous method, plot_surface() is used to draw scalars: functions of the form f(x, y)=z, but Matplotlib can also draw 3d surfaces in a more general way:
# Data generation
angle = np.linspace(0.2 * np.pi, 32)
theta, phi = np.meshgrid(angle, angle)
r, r_w = 25..1.
x = (r_w + r * np.cos(phi)) * np.cos(theta)
y = (r_w + r * np.cos(phi)) * np.sin(theta)
z = r * np.sin(phi)
# draw
fig = plt.figure()
ax = fig.gca(projection = '3d')
ax.set_xlim3d(-1.1)
ax.set_ylim3d(-1.1)
ax.set_zlim3d(-1.1)
ax.plot_surface(x, y, z, color = 'c', edgecolor='m', rstride = 2, cstride = 2)
plt.show()
Copy the code
You can also replace the plot_surface() call with plot_wireframe() to get a wireframe view of the ring:
ax.plot_wireframe(x, y, z, edgecolor='c', rstride = 2, cstride = 1)
Copy the code
Draws 2D graphics in 3D coordinate axes
An effective way to annotate 3d graphics is to use 2d graphics:
x = np.linspace(-3.3.256)
y = np.linspace(-3.3.256)
x_grid, y_grid = np.meshgrid(x, y)
z = np.exp(-(x_grid ** 2 + y_grid ** 2))
u = np.exp(-(x ** 2))
fig = plt.figure()
ax = fig.gca(projection = '3d')
ax.set_zlim3d(0.3)
ax.plot(x, u, zs=3, zdir='y', lw = 2, color = 'm')
ax.plot(x, u, zs=-3, zdir='x', lw = 2., color = 'c')
ax.plot_surface(x_grid, y_grid, z, color = 'b')
plt.show()
Copy the code
Axes3D instances also support common 2d rendering commands such as plot() :
ax.plot(x, u, zs=3, zdir='y', lw = 2, color = 'm')
Copy the code
Axes3D instance calls to plot() have two new optional parameters: zdir: Determines which plane to draw a 2D plot on, with optional values including x, y, or z; Zs: Determines the offset of the plane. Therefore, to embed a 2d graphic into a 3D graphic, simply use the 2D primitive for the Axes3D instance, along with the optional parameters, ZDIR and ZS, to place the desired rendered graphic plane. Next, let’s actually look at an example of stacking 2D bar charts in 3D space:
import numpy as np
from matplotlib import cm
import matplotlib.colors as col
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
# Data generation
alpha = 1. / np.linspace(1.8.5)
t = np.linspace(0.5.16)
t_grid, a_grid = np.meshgrid(t, alpha)
data = np.exp(-t_grid * a_grid)
# draw
fig = plt.figure()
ax = fig.gca(projection = '3d')
cmap = cm.ScalarMappable(col.Normalize(0.len(alpha)), cm.viridis)
for i, row in enumerate(data):
ax.bar(4 * t, row, zs=i, zdir='y', alpha=0.8, color=cmap.to_rgba(i))
plt.show()
Copy the code
Series of links
Matplotlib common statistical graph drawing
Matplotlib uses custom colors to draw statistics
Matplotlib controls line style and line width
Matplotlib custom style to draw beautiful statistics
Matplotlib adds text instructions to the graph
Matplotlib adds comments to the graph
Matplotlib adds auxiliary grids and auxiliary lines to the graph
Matplotlib adds custom shapes
Matplotlib controls the scale spacing and labeling of the coordinate axes
Matplotlib uses logarithmic scales and polar coordinates
Matplotlib draws subgraphs
Matplotlib custom graph scale
Matplotlib graph output and save
Matplotlib more useful graphics for drawing