很多时候,我们要对三维空间中的数据进行可视化展示和分析。然而,由于三维空间内的数据可视化涉及透视、投影等操作,其复杂性远高于平面内的数据可视化。因此我花了一下午的时间,调研了一下相关工具,汇总成本文。文中一些疏漏之处,还请多多指教。
一、基于python的方法
(一)matplotlib
matplotlib在科学技术和统计分析中多有使用,但是以往人们用得多的是他的二维数据展示功能,例如各种统计图的绘制。但是matplotlib也可也展示三维数据。下面是一个例子
1 2 3 4 5 6 7 8 9 10 11
| 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)
ax = plt.axes(projection='3d') ax.plot3D(x, y, z, 'gray') plt.show()
|
结果如下图所示:
当然,也可也创建三维曲面:
1 2 3 4 5 6 7 8 9 10
| x = np.outer(np.linspace(-2, 2, 30), np.ones(30))
y = x.copy().T
z = np.cos(x ** 2 + y ** 2)
ax = plt.axes(projection='3d') ax.plot_surface(x, y, z,cmap='viridis', edgecolor='none') plt.show()
|
然而,上述方法也有缺点。maplotlib的三维绘图工具本质上只是将三维结构中的点 “拍扁” 到二维空间中,因此如果两个三维结构有相交,这种绘图方法会导致两个图形的空间位置错乱,而且根本看不出相交线。
一个例子:
1 2 3 4 5 6 7 8 9 10 11 12
| x = np.outer(np.linspace(-2, 2, 30), np.ones(30))
y = x.copy().T
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()
|
可以从上图中看到,函数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 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()
|
对于多个相交的曲面,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()
|
(三)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
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) grid2 = pv.StructuredGrid(x, y, z2) pl = pv.Plotter() pl.add_mesh(grid1, color="#5599aa") pl.add_mesh(grid2, color="#aa9965") pl.add_axes(line_width=5, labels_off=False) pl.show()
|
二、基于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; z2 = x.^2 - y;
mesh(x,y,z1); hold on; mesh(x,y,z2); xlabel('x'), ylable('y'), zlabel('z') show()
|
结果如下图所示:
旧评论系统备份:
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安装) >
|