之前讲的都是二维的坐标系,可视化中还能在三维坐标系中绘制三维图像。
这个时候就需要用到我们Matplotlib中的一个工具,mplot3d用来专门绘制三维图像的工具,在我们安装Matplotlib的时候就已经安装好了mplot3d。
from mpl_toolkits import mplot3d
首先导入子模块,然后再完成案例;
fig = plt.figure()
ax = plt.axes(projection='3d')
plt.show()
结果就是这样的一个三维坐标系,在三维坐标系里面,点的坐标是通过x,y,z来确定的,如果要在三维坐标系中画出曲线图或者散点图,可以使用ax.plot3D和ax.scatter3D函数。
fig = plt.figure()
ax = plt.axes(projection='3d')
x_line = np.linspace(0,15,100)
y_line = np.sin(x_line)
z_line = np.cos(x_line)
ax.plot3D(x_line,y_line,z_line,'y')
x_point = 15 * np.random.random(100)
y_point = np.sin(x_point)
z_point = np.cos(x_point)
ax.scatter3D(x_point,y_point,z_point,c=x_point,cmap='Blues')
观察运行结果还是很好理解的就是多了一个z轴的参数,ax.scatter3D方法里面的c表示的是指定每个点的颜色,cmap表示的也是颜色,具体代码详情可以参考绘制图像也可以查看帮助文档:
scatter(xs, ys, zs=0, zdir='z', s=20, c=None, depthshade=True, *args, **kwargs)
三维等高线图:
x = np.linspace(-5,5,30)
y = np.linspace(-5,5,30)
X,Y = np.meshgrid(x,y)
Z = np.sin(np.sqrt(X**2 + Y**2))
ax.contour3D(X,Y,Z,50,cmap='Blues')
ax.set_xlabel('x')
ax.set_ylabel('y')
ax.set_zlabel('z')
ax.view_init(60,35)
运行结果
观察上方的代码:x,y是两个一维数组,np.meshgrid函数构建矢量化的对象XY,记得是大写,这样就不会起冲突,XY是两组30*30并且数值对应的矩阵,这样通过XY就可以构建平面的网格,ax.view_init是实现坐标系方位旋转。
莫比乌斯环
就是上面这个东西的样子,方程式如下
是不是感觉好难,我也觉得,那我们先写个案例看看:
from matplotlib.tri import Triangulation
fig = plt.figure()
ax = plt.axes(projection='3d')
u = np.linspace(0,2 * np.pi,30)
v = np.linspace(-0.5,0.5,8)/2.0
v,u = np.meshgrid(v,u)
phi = 0.5 * u
r = 1+ v * np.cos(phi)
x = np.ravel(r * np.cos(u))
y = np.ravel(r * np.sin(u))
z = np.ravel(v * np.sin(phi))
tri = Triangulation(np.ravel(v),np.ravel(u))
ax.plot_trisurf(x,y,z,triangles=tri.triangles,cmap='viridis',linewidth=0.2)
ax.set_xlim(-1,1)
ax.set_ylim(-1,1)
ax.set_zlim(-1,1)
观察上面的代码别忘了导入from matplotlib.tri import Triangulation,这个模块是Matplotlib专门针对非结构化网格作图的模块,非结构网格是没有规则拓扑关系的网格,它通常由 polygon triangulation 组成。非结构化网格是指网格区域内的内部点不具有相同的毗邻单元。即与网格剖分区域内的不同内点相连的网格数目不同。网格中的每个元素都可以是二维的多边形或者三维多面体,其中最常见的是二维的三角形以及三维的四面体。在每个元素之间没有隐含的连通性。 为此在tri模块中提供了一个Triangulation的类,实现元素为三角形的非结构化网格。
points_xy = np.array([[0.1,0.2],[0.5,1],[1,0.2],[0.2,0.4]])
triangles = [[0,2,3],[2,3,1]]
triang = Triangulation(points_xy[:,0],points_xy[:,1],triangles=triangles)
plt.triplot(triang,marker='o')
观察上面的代码points_xy创建了4个点的坐标点,并且可以通过索引表示这4个点的顺序,用4个点构建两个相邻的三角形,triangles就规定了两个三角形是用哪些点构成的,并且共同的一条边是哪条,比如第一个三角形是用第0个点,第2个点,第3个点,也就是坐标[0.1,0.2],[1,0.2],[0.2,0.4],这三个点构成的,构成每个三角形的点按照顺序逆时针排列,这种方式是Triangulation里面的triangles参数规定的。
上面那个是二维非结构化三角形网格的函数,那三维的非结构化三角形网格怎么画呢:
fig = plt.figure()
ax = plt.axes(projection='3d')
points_xy = np.array([[0.1,0.2],[0.5,1],[1,0.2],[0.2,0.4]])
triangles = [[0,2,3],[2,3,1]]
z = [0.1,0.2,0.3,0.4]
triang = Triangulation(points_xy[:,0],points_xy[:,1],triangles=triangles)
ax.plot_trisurf(triang,z)
添加一个z维度就可以画出来了。