我有一个3维的numpy数组。我想显示(在matplotlib中)此数组的等值面的漂亮3D图(或更严格地说,显示通过在采样点之间进行插值定义的3D标量字段的等值面)。
matplotlib的mplot3D部分提供了不错的3D绘图支持,但是(据我所知),其API没有任何东西可以简单地获取标量值的3D数组并显示等值面。但是,它确实支持显示多边形的集合,因此大概可以实现行进立方体算法来生成此类多边形。
It does seem quite likely that a scipy-friendly marching cubes has already been implemented somewhere and that I haven't found it, or that I'm missing some easy way of doing this. Alternatively I'd welcome any pointers to other tools for visualising 3D array data easily usable from the Python/numpy/scipy world.
Just to elaborate on my comment above, matplotlib's 3D plotting really isn't intended for something as complex as isosurfaces. It's meant to produce nice, publication-quality vector output for really simple 3D plots. It can't handle complex 3D polygons, so even if implemented marching cubes yourself to create the isosurface, it wouldn't render it properly.
但是,您可以做的是使用mayavi(它的mlab API比直接使用mayavi更为方便),它使用VTK处理和可视化多维数据。
作为一个快速示例(从mayavi画廊示例之一进行了修改):
import numpy as np
from enthought.mayavi import mlab
x, y, z = np.ogrid[-10:10:20j, -10:10:20j, -10:10:20j]
s = np.sin(x*y*z)/(x*y*z)
src = mlab.pipeline.scalar_field(s)
mlab.pipeline.iso_surface(src, contours=[s.min()+0.1*s.ptp(), ], opacity=0.3)
mlab.pipeline.iso_surface(src, contours=[s.max()-0.1*s.ptp(), ],)
mlab.show()
完善!apt-get install mayavi2,运行您的代码。正是我要的东西。多年来,我一直在想是否应该以某种方式不使用VTK。这似乎是从科学界进入它的好方法。天哪,就像发现一个全新的星球...
还有一个mlab outline3d函数可以使上述内容更加简单:github.enthought.com/mayavi/mayavi/auto/…
只是警告您,“用于轮廓的特定值列表”功能
contour3d
已中断了很长时间。(它可能是最近修复的,但是如果它不起作用,请不要感到惊讶。)如果您只想在最小值和最大值之间指定5个轮廓,但是传入一个特定值列表(例如,例如[0.1, 0.5, 0.9, 1.5, 2.5]
)将无声地失败。总的来说,它非常漂亮,这是我遇到的唯一烦人的错误!它也可以很好地处理非常大的数据集!取消这一点,无论值多少,传入特定值的列表似乎都可以在最新版本中完美运行。
我一直在研究它可以与一些512 ^ 3数组一起很好地工作。有趣的是,contour3d的峰值内存消耗似乎比上述“流水线”版本要低得多(分别为2.5GB和8GB;所幸我使用的是64位大型系统)。但是,还没有尝试使用np.array(...,dtype = np.int16)之类的东西做任何事情(我认为np数组默认为double)。