如何对3D数据进行可视化展示

很多时候,我们要对三维空间中的数据进行可视化展示和分析。然而,由于三维空间内的数据可视化涉及透视、投影等操作,其复杂性远高于平面内的数据可视化。因此我花了一下午的时间,调研了一下相关工具,汇总成本文。文中一些疏漏之处,还请多多指教。

一、基于python的方法

(一)matplotlib

matplotlib在科学技术和统计分析中多有使用,但是以往人们用得多的是他的二维数据展示功能,例如各种统计图的绘制。但是matplotlib也可也展示三维数据。下面是一个例子

1
2
3
4
5
6
7
8
9
10
11
#导入三维工具包mplot3dfrom mpl_toolkits import mplot3d
import numpy as np
import matplotlib.pyplot as plt
#从三个维度构建
z = np.linspace(0, 1, 100)
x = z * np.sin(20 * z)
y = z * np.cos(20 * z)
#创建3d绘图区域
ax = plt.axes(projection='3d')
ax.plot3D(x, y, z, 'gray')
plt.show()

结果如下图所示:

figure1

当然,也可也创建三维曲面:

1
2
3
4
5
6
7
8
9
10
#求向量积(outer()方法又称外积)
x = np.outer(np.linspace(-2, 2, 30), np.ones(30))
#矩阵转置
y = x.copy().T
#数据z
z = np.cos(x ** 2 + y ** 2)
#绘制曲面图
ax = plt.axes(projection='3d')
ax.plot_surface(x, y, z,cmap='viridis', edgecolor='none')
plt.show()

figure2

然而,上述方法也有缺点。maplotlib的三维绘图工具本质上只是将三维结构中的点 “拍扁” 到二维空间中,因此如果两个三维结构有相交,这种绘图方法会导致两个图形的空间位置错乱,而且根本看不出相交线。

一个例子:

1
2
3
4
5
6
7
8
9
10
11
12
#求向量积(outer()方法又称外积)
x = np.outer(np.linspace(-2, 2, 30), np.ones(30))
#矩阵转置
y = x.copy().T
#数据z
z1 = x**2+y
z2 = x**2-y
#绘制曲面图
ax = plt.axes(projection='3d')
ax.plot_surface(x, y, z1,cmap='viridis', edgecolor='none')
ax.plot_surface(x, y, z2,cmap='plasma', edgecolor='none')
plt.show()

figure3

可以从上图中看到,函数z2的图像全部遮盖住了z1的图像。然而从函数表达式中我们可以得知,z1与z2有一个相交的曲线(y=0, z=x^2),这并不能从图中体现出来。通过这个例子我们可以知道,使用matplotlib绘制三维函数图像,虽然可行(_真的吗?_),但是总归不严谨。

(二)Mayavi

Mayavi是一个3-D科学数据可视化工具,其官网为https://mayavi.readthedocs.io/。可以通过下列的conda指令进行安装:

1
2
conda install -c conda-forge pyqt # PyQt5为Mayavi所依赖,因此需要预先安装
conda install -c conda-forge mayavi

Mayavi是一个很大的工具包,因此安装耗时也比较长,请耐心等待。安装成功后,在命令行输入指令mayavi2 --version,如果能够正确输出版本号(例如Mayavi 4.7.2),则表明安装成功。

Mayavi可以以一个独立的应用程序的形式运行,当然也可也在python代码中调用。Mayavi提供了一个叫做mlab的接口,通过from mayavi import mlab在python中导入这个接口,即可像matplotlib一样使用。

使用mayavi进行数据可视化展示的一个示例:

1
2
3
4
5
6
7
8
import numpy as np
from mayavi import mlab
x, y = np.ogrid[-2:2:20j, -2:2:20j]
z = x * np.exp( - x**2 - y**2)
pl = mlab.surf(x, y, z, warp_scale="auto")
mlab.axes(xlabel='x', ylabel='y', zlabel='z')
mlab.outline(pl)
mlab.show()

figure4

对于多个相交的曲面,Mayavi的展示效果要强于matplotlib,其可以很好的反映两个曲面的相交情况。下图展示一个例子(仍然以上一小节中的函数z1和z2为例):

1
2
3
4
5
6
7
8
9
10
11
import numpy as np
from mayavi import mlab
x, y = np.ogrid[-2:2:20j, -2:2:20j]
z1 = x**2 + y
z2 = x**2 - y
pl1 = mlab.surf(x, y, z1, warp_scale="auto", colormap='autumn')
pl2 = mlab.surf(x, y, z2, warp_scale="auto", colormap='winter')
mlab.axes(xlabel='x', ylabel='y', zlabel='z')
mlab.outline(pl1)
mlab.outline(pl2)
mlab.show()

figure5

(三)PyVista

PyVista是另一个基于Python的三维数据可视化软件。其官网为https://docs.pyvista.org/index.html。安装方法也很简单,直接执行指令:

1
conda install -c conda-forge pyvista

即可。

使用PyVista绘图的一个示例如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import numpy as np
import pyvista as pv
from pyvista import examples
# Make data
x = np.arange(-2, 2, 0.05)
y = np.arange(-2, 2, 0.05)
x, y = np.meshgrid(x, y)
z1 = x**2 + y
z2 = x**2 - y
grid1 = pv.StructuredGrid(x, y, z1) # 绘制函数z1的多边形模型
grid2 = pv.StructuredGrid(x, y, z2) # 绘制函数z2的多边形模型
pl = pv.Plotter() # 创建绘图对象
pl.add_mesh(grid1, color="#5599aa") # 将函数z1的多边形模型加入绘图对象中,并设置颜色
pl.add_mesh(grid2, color="#aa9965") # 将函数z2的多边形模型加入绘图对象中,并设置颜色
pl.add_axes(line_width=5, labels_off=False) # 左下角展示坐标轴
pl.show() # 图像展示

figure6

二、基于matlab的方法

前面我们讲了三种基于python的三维结构展示方法,但是其实很多科学计算软件内置了三维数据可视化方法,例如matlab。下面举一个例子

1
2
3
4
5
6
7
8
9
10
11
12
clear;%清除之前所有已有的变量
X=[-2:0.05:2];
Y=[-2:0.05:2];
[x,y] = meshgrid(X,Y);
z1 = x.^2 + y; % 函数z1
z2 = x.^2 - y; % 函数z2

mesh(x,y,z1);
hold on; % 保持上一个图形不消失,继续绘制
mesh(x,y,z2);
xlabel('x'), ylable('y'), zlabel('z')
show()

结果如下图所示:

figure7



旧评论系统备份:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
Hazel(2022-10-19 14:53:41):
咱就说,可以每周讲一个用法吗?可以别人定那种?
我还挺好奇内积的,以及希望矩阵的一点点用法多搞一下
或者是偏数学的东西,比如多元线性回归、最大似然估计啦之类的?

Hazel(2022-10-19 14:56:40):
还有就是,可以直接pip install 去安装吗?为什么要conda install 呀

> WarrenZhang(2022-10-19 15:09:40):
> 可以的哈哈哈,那我试一下,下周写一点数学方面的文章(不过以前没写过这种类型的文章,不保证质量😂)
>
> WarrenZhang(2022-10-19 15:14:32):
> 也可以的,不过我用conda装习惯了,这次也就用了conda,没有踩pip install的坑。
> 或许你可以试试用pip install?这几个工具的文档都很全,里面列了pip的安装方法,例如mayavi就可以用
> pip install mayavi
> pip install PyQt5
> 来安装(但是貌似这种安装方法需要手动安装vtk,然而vtk好像要用conda安装)
>