mlab:用于3D绘图的Python脚本

章节摘要

本节介绍了mlab API,用于将Mayavi用作脚本或交互式会话中的简单绘图。这是对使用Python在Matlab或IDL中进行3D绘图感兴趣的人们的主要切入点。如果您对mlab中公开的所有功能列表感兴趣,请参见MLab参考。

mayavi.mlab模块,我们称之为MLAB,提供了一种简便的方式在做在脚本或者交互提示与单行可视化数据matplotlib pylab接口,但在使用Mayavi2三维可视化的重点。这使用户能够执行快速3D可视化,同时能够使用Mayavi的强大功能。

Mayavi的mlab旨在以非常适合脚本编写的方式使用,并且不提供完全面向对象的API。可以与IPython交互使用。

警告

 

当将IPython与mlab结合使用时,如以下示例所示,必须使用如下--gui=qt命令行选项来调用IPython :

$ ipython --gui=qt

在最新版本的IPython上,可以通过以下方式在IPython本身中将其打开:

In []: %gui qt

如果引发以下异常:

ValueError: API 'QString' has already been set to version 1

这是PyQt和PySide之间设置不兼容的结果。解决方案是运行。可以在ipython文档页面上找到更多详细信息。QT_API=pyqt ETS_TOOLKIT=qt4 ipython

如果由于某些原因Mayavi无法通过Qt后端运行,您还可以尝试通过以下方式使用wxPython后端:

$ ETS_TOOLKIT=wx
$ ipython --gui=wx

有关使用mlab和运行脚本的更多详细信息,请阅读“运行mlab脚本”部分

在本节中,我们首先介绍简单的绘图函数,以创建3D对象作为numpy数组的表示形式。然后我们解释(1)如何修改颜色或字形大小等属性或将其用于表示数据;(2)如何通过对话框交互地修改通过mlab创建的可视化,(3)如何运行脚本和动画。最后,我们展示了mlab的更高级用法, 其中在脚本中构建了完整的可视化管道,并给出了一些应用这些工具来可视化体积标量和矢量数据的详细示例。

节内容

  • 演示
  • numpy数组的3D绘图功能
  • 更改创建的视觉对象的外观
  • 人物,传说,照相机和装饰品
  • 运行mlab脚本
  • 动画数据
  • 用mlab组装管道
  • 一些可视化案例研究

演示

首先,这是一个漂亮的示例,将球形谐波显示为表面:

# Create the data.
from numpy import pi, sin, cos, mgrid
dphi, dtheta = pi/250.0, pi/250.0
[phi,theta] = mgrid[0:pi+dphi*1.5:dphi,0:2*pi+dtheta*1.5:dtheta]
m0 = 4; m1 = 3; m2 = 2; m3 = 3; m4 = 6; m5 = 2; m6 = 6; m7 = 4;
r = sin(m0*phi)**m1 + cos(m2*phi)**m3 + sin(m4*theta)**m5 + cos(m6*theta)**m7
x = r*sin(phi)*cos(theta)
y = r*cos(phi)
z = r*sin(phi)*sin(theta)

# View it.
from mayavi import mlab
s = mlab.mesh(x, y, z)
mlab.show()

上面的示例中的大部分代码是创建数据。一行就足以将其可视化。这将产生以下可视化效果:

mlab:用于3D绘图的Python脚本_第1张图片

可视化是由mesh()上面的单个功能创建的。

mlab提供了此类示例(请参见 test_contour3d,test_points3d,test_plot3d_anim等)。上面的演示可以通过test_mesh获得。在IPython下,可以通过在mlab.test上完成选项卡找到这些内容。您还可以通过方便的mlab.test_contour3d ??在IPython中检查源代码?。

numpy数组的3D绘图功能

可视化可以通过在numpy数组上运行的一组函数在mlab中创建。

所述MLAB绘图函数采取numpy的阵列作为输入,描述 xyz该数据的坐标。他们构建了完善的可视化:他们创建数据源,必要时进行过滤,并添加可视化模块。与pylab类似,可以通过关键字参数对它们的行为以及由此创建的可视化进行微调。此外,它们都返回创建的可视化模块,因此也可以通过更改该模块的属性来修改可视化。

注意

 

在本节中,我们仅列出不同的功能。用户指南末尾的MLab参考中详细描述了每个功能,并附带附图和示例。请点击链接。

0D和1D数据

   
mlab:用于3D绘图的Python脚本_第2张图片 points3d()
曲线字形(像点)所提供的数据的位置,通过描述xyz 相同形状的numpy的阵列。
mlab:用于3D绘图的Python脚本_第3张图片 plot3d()
重复所提供的数据,通过所描述之间排队x, yz具有相同长度的一维numpy的阵列。

2D数据

   
mlab:用于3D绘图的Python脚本_第4张图片 imshow()
查看2D阵列作为图像。
mlab:用于3D绘图的Python脚本_第5张图片 surf()
将2D数组作为地毯图查看,其中z轴通过高程表示数组点的值。
mlab:用于3D绘图的Python脚本_第6张图片 contour_surf()
以线轮廓查看2D阵列,并根据阵列点的值进行提升。
mlab:用于3D绘图的Python脚本_第7张图片 mesh()
绘制由三个二维阵列中所述的表面,x, yz赋予数据点作为网格的坐标。
与不同surf(),曲面是由定义的 xy并且z没有特权方向进行协调。可以创建更复杂的曲面。
mlab:用于3D绘图的Python脚本_第8张图片 barchart()
用条形图(例如直方图)绘制s带有明确坐标数组xy和 的数组或一组点z
此功能非常通用,可以接受2D或3D阵列,也可以包含点云来定位条。
mlab:用于3D绘图的Python脚本_第9张图片 triangular_mesh()
绘制一个三角网格,通过完全指明的 xyz其顶点的坐标,并且第(n,3)的三角形的索引的数组。

垂直比例 surf()contour_surf()

surf()contour_surf()可用作2D数据的3D表示。默认情况下,z轴应该与x和y轴使用相同的单位,但是可以自动缩放以提供2/3的宽高比。可以通过指定“ warp_scale ='auto'”来控制此行为。

从数据点到曲面。

仅仅知道数据点的位置不足以定义表面,还需要连接信息。用的功能surf()mesh(),该连通性信息被隐含地从输入阵列的形状提取的:在网格上被连接在2D输入数组相邻数据点,并且将数据的所在。使用函数 triangular_mesh(),可以明确指定连接性。通常,连通性不是固定的,但也不是事先知道的。数据点位于表面上,我们想绘制隐式​​定义的表面。所述delaunay2d滤波器做所需的最近邻匹配,和内插,如图中(表面从不规则数据例)。

3D数据

   
mlab:用于3D绘图的Python脚本_第10张图片 contour3d()
绘制定义为3D阵列的体积数据的等值面。
mlab:用于3D绘图的Python脚本_第11张图片 quiver3d()
绘制箭头以表示数据点处的向量。的xyz位置由numpy的阵列,以及所指定的uvw 所述矢量的分量。
mlab:用于3D绘图的Python脚本_第12张图片 flow()
绘制颗粒的轨迹沿着由三个三维阵列给予描述的矢量场u, vw在网格上的组件。
mlab:用于3D绘图的Python脚本_第13张图片 volume_slice()
绘制通过体积数据切片的交互式图像平面。

结构化或非结构化数据

contour3d()volume_slice()并且flow()需要有序数据(以便能够在各点之间进行插值),而 quiver3d()适用于任何点集。功能文档中详细介绍了所需的结构。

注意

 

通过组装数据源过滤器和模块,可以创建许多更丰富的可视化效果。请参阅“ 使用mlab组装管道”和“ 一些可视化案例研究”部分。

更改创建的视觉对象的外观

加入的颜色或大小的变化

颜色:

可以使用函数的'color'关键字参数明确指定由绘图函数创建的对象的颜色。然后将该颜色均匀地应用于所有创建的对象。

如果要在可视化中改变颜色,则需要为每个数据点指定标量信息。某些函数会尝试猜测这些信息:对于带有矢量的函数,这些标量默认为矢量的范数,对于有意义的函数,则默认为z标高,例如surf()barchart()

使用用于查找表的颜色图(也称为LUT)将此标量信息转换为颜色。可能的颜色图列表为:

accent       flag          hot      pubu     set2
autumn       gist_earth    hsv      pubugn   set3
black-white  gist_gray     jet      puor     spectral
blue-red     gist_heat     oranges  purd     spring
blues        gist_ncar     orrd     purples  summer
bone         gist_rainbow  paired   rdbu     winter
brbg         gist_stern    pastel1  rdgy     ylgnbu
bugn         gist_yarg     pastel2  rdpu     ylgn
bupu         gnbu          pink     rdylbu   ylorbr
cool         gray          piyg     rdylgn   ylorrd
copper       greens        prgn     reds
dark2        greys         prism    set1

选择颜色图,最适合您的可视化效果的最简单方法是使用GUI(如下一节所述)。可以在“颜色和图例”节点中找到用于设置颜色图的对话框。

要暂时使用自定义颜色表,您需要编写特定的代码,如“自定义颜色表”示例中所示。

字形的大小:
 

标量信息也可以以许多不同的方式显示。例如,它可用于调整位于数据点的字形的大小。

一个警告:夹紧:相对或绝对缩放 给定六个点,它们在点间距为1的直线上:

x = [1, 2, 3, 4, 5, 6]
y = [0, 0, 0, 0, 0, 0]
z = y

如果我们表示此数据集上的标量从0.5到1:

s = [.5, .6, .7, .8, .9, 1]

我们使用来将数据集表示为球体,points3d()并且将标量映射到球体的直径:

from mayavi import mlab
pts = mlab.points3d(x, y, z, s)

默认情况下,球体的直径不是“固定”的,换句话说,标量数据的最小值表示为零直径,而最大值与点间距离成比例。从结果图中可以看出,缩放比例只是相对的:

mlab:用于3D绘图的Python脚本_第14张图片

此行为为所有数据集提供可见点,但是如果标量表示字形的大小与指定位置在同一单位中,则可能不希望这样做。

在这种情况下,应通过指定所需的比例因子来关闭自动缩放功能:

pts = mlab.points3d(x, y, z, s, scale_factor=1)
mlab:用于3D绘图的Python脚本_第15张图片

警告

 

在Mayavi的早期版本(包括最多3.1.0)中,字形不会自动缩放,因此,由于字形非常小,因此可视化效果似乎是空的。此外,字形的最小直径被限制为零,因此字形不会绝对缩放,除非您指定:

pts.glyph.glyph.clamping = False
附加标量或向量的更多表示:
 

还有许多种方法来表示附加到数据的标量或矢量信息。例如,可以使用WarpScalar滤波器将标量数据“扭曲”为位移,或者可以将标量数据的范数提取为标量分量,该分量可以使用ExtractVectorNorm滤波器使用等值面进行可视化。

显示多个数量:
 

您可能想显示与一个标量相关的颜色,而将第二个用于等高线或高程。这是可行的,但需要一些工作:请参见“原子轨道示例”。

如果您只想显示大小为一个数量给定的点,然后显示颜色为第二个点,则可以使用一个简单的技巧:使用矢量范数添加大小信息,使用标量添加颜色信息,创建quiver3d()图选择将字形转换为对称字形,并使用标量表示颜色:

x, y, z, s, c = np.random.random((5, 10))
pts = mlab.quiver3d(x, y, z, s, s, s, scalars=c, mode='sphere')
pts.glyph.color_mode = 'color_by_scalar'
# Finally, center the glyphs on the data point
pts.glyph.glyph_source.glyph_source.center = [0, 0, 0]

更改对象的规模和位置

每个MLAB函数接受一个程度关键字参数,其允许设置其(X,Y,Z)范围。这样既可以控制不同方向的缩放比例,也可以控制中心的位移。请注意,当您使用此功能时,将相同的数据区传递给可视化相同数据的其他模块可能会很有用。如果您不这样做,它们将不会共享相同的位移和比例。

surf()contour_surf()barchart()功能,这些功能由在高度变换的值显示2D阵列,还采取 warp_scale参数,以控制垂直缩放。

以交互方式更改对象属性

Mayavi以及mlab允许您交互式地修改可视化。

通过单击图形工具栏中的mayavi图标,或使用show_pipeline()mlab命令,可以显示Mayavi管道树。现在可以使用该对话框来更改可视化效果,方法是双击每个对象以编辑其属性(如本手册其他部分所述),也可以通过在管道上使用此图标或右键单击来添加新模块或过滤器管道中对象上的菜单。

mlab:用于3D绘图的Python脚本_第16张图片

记录功能

通过按下管道视图工具栏上的红色圆形按钮,可以找到此对话框的一个非常有用的功能。这将打开一个记录器,该记录器通过对话框以交互方式跟踪对可视化所做的更改,并生成有效的Python代码行。要了解有关在管道中浏览程序的信息,请参见 Mayavi可视化的组织:管道。

此外,对于mlab函数返回的每个对象,都会 this_object.edit_traits()弹出一个对话框,该对话框可用于交互式地编辑对象的属性。如果在输入此命令时未显示对话框,请参阅“运行mlab脚本”。

使用mlab与全Envisage的UI

有时编写mlab脚本很方便,但是仍然使用完整的envision程序,因此您可以单击菜单并使用其他模块等。为此,您可以在创建mlab图之前执行以下操作:

from mayavi import mlab
mlab.options.backend = 'envisage'
f = mlab.figure()
# ...

这将为您提供完整的UI,而不是默认的简单窗口。

人物,传说,照相机和装饰品

处理几个数字

figure()为了与Matlab和pylab兼容,所有mlab函数都在当前场景(也称为)上 运行。不同的数字由可以为整数或字符串的键索引。调用figure()提供键的函数将返回相应的图形(如果存在),或创建一个新图形。可以使用gcf()函数检索当前图形。可以使用draw()功能进行刷新,使用 保存到图片文件,使用savefig()清除clf()

人物装饰

轴可围绕与所述可视化对象被添加axes() 功能,并且标签可以使用被设置xlabel()ylabel() 和zlabel()功能。同样,outline()在对象周围创建轮廓。title()在图形上添加标题。

颜色条可用于反映用于显示值的色图(在VTK术语中为LUT或查找表)。colorbar()为最后创建的对象创建一个颜色条,尝试猜测是使用矢量数据还是使用标量数据颜色图。的scalarbar()和 vectorbar()功能的扫描被用来专门创建彩条标量或矢量数据。

可以使用将小xyz三合会添加到该图 orientation_axes()

警告

 

orientation_axes()被命名为orientationaxes 版本3.2之前。

移动相机

可以使用该view() 功能设置摄像机的位置和方向。用欧拉角和到焦点的距离来描述它们。该view()功能试图猜测摄像机的正确滚动角度以获得令人愉悦的视野,但有时会失败。的roll() 显式地设定照相机的侧倾角(这可以是通过按下控制键,同时拖动鼠标时,看到场景交互实现与场景相互作用)。

view()roll()函数返回他们采取作为参数的不同角度和距离的当前值。结果,可以使用以下方式存储并重置交互获得的视点:

# Store the information
view = mlab.view()
roll = mlab.roll()

# Reposition the camera
mlab.view(*view)
mlab.roll(roll)

围绕自身旋转相机

您还可以使用相机对象的滚动,偏航 和俯仰方法围绕自身旋转相机。这将移动焦点:

f = mlab.gcf()
camera = f.scene.camera
camera.yaw(45)

view()roll()函数不同,角度是递增的,而不是绝对的。

修改缩放和视角

摄像机完全由其位置,焦点和视角(属性“位置”,“焦点_”,“视角”)定义。摄像头方法“缩放”以指定的比率递增地更改视角,而“移动摄影机”方法则在保持焦点恒定的同时沿其轴平移摄像头。该move() 功能在这些方面也可能有用。

注意

 

相机平行尺

除了mlab.view和mlab.roll返回和设置的信息外,还需要最后一个参数来完全定义视点:控制摄像机视角的摄像机的平行比例尺。可以使用以下代码读取(或设置)它:

f = mlab.gcf()
camera = f.scene.camera
cam.parallel_scale = 9

运行MLAB脚本

和Mayavi的其余部分一样,Mlab是一个交互式应用程序。如果您尚未处于交互式环境中(请参见下一段),则要与图形或其余图形元素进行交互,则需要使用该show()功能。例如,如果您正在编写脚本,则show()每次显示一个或多个图形并允许用户与其交互时,都需要调用一次。

使用MLAB交互

使用IPython,可以交互式运行mlab指令,也可以使用IPython的%run命令在脚本中运行:

In [1]: %run my_script

您需要使用–gui = qt选项启动IPython。在这种环境下,绘图命令是交互式的:它们对图形具有直接作用,从而减轻了使用该功能的需要 。show()

Mlab也可以在mayavi2应用程序的Python外壳中或在基于wxPython的应用程序的任何交互式Python外壳中(例如,其他基于Envisage的应用程序,或SPE,Stani的Python编辑器)以交互方式使用。

与Matplotlib一起使用

如果要在IPython中将Matplotlib的交互式绘图与Mayavi的mlab一起使用,则应:

  • 使用以下命令启动IPython:

    $ ipython --matplotlib=qt
    
  • 或者,使用–gui = qt选项启动IPython :

    $ ipython --gui=qt
    

    之前导入任何matplotlib模块,输入下面的Python命令:

    >>> import matplotlib
    >>> matplotlib.use('Qt4Agg')
    >>> matplotlib.interactive(True)
    
  • 也可以--pylab如下使用IPython的选项:

    $ ipython --pylab=qt
    

如果要在IPython中使matplotlib和mlab在默认情况下一起工作,则可以通过编辑〜/ .matplotlib / matplotlibrc以添加以下行来更改默认的matplotlib后端 :

backend     : Qt4Agg

如果由于某种原因Qt后端不起作用,则可以使用wx后端。为此,您可以执行以下操作:

$ ETS_TOOLKIT=wx
$ ipython --gui=wx

注意,就Mayavi而言,它使用ETS_TOOLKIT环境变量选择适当的工具箱。如果未设置此选项,则以版本相关的顺序尝试受支持的工具包,直到成功为止。在最新版本的traitsui中,默认值为Qt。可能的选项ETS_TOOLKIT是:

  • qt4:使用Qt后端(PySide或PyQt4),
  • wx:使用wxPython,
  • null:不使用任何UI工具包。

捕获mlab图以整合到pylab中

从Mayavi版本3.4.0开始,screenshot()可以使用mlab截取当前图形的屏幕截图,以集成到matplotlib图中。

在脚本

可以将Mlab命令写入文件以形成脚本。可以使用文件->打开文件菜单项将该脚本加载到Mayavi应用程序中,并使用文件->刷新代码菜单项或按来执行该脚本Control-r。它也可以在Mayavi应用程序启动期间使用-x命令行开关执行。

如上所述,当在交互式环境之外运行时(例如,使用python myscript.py),您需要调用 show()函数(如上面的演示中所示)以暂停脚本并使用户与图形交互。

您还可以show()用来装饰函数,并使其在事件循环中运行,从而为您提供更大的灵活性:

from mayavi import mlab
from numpy import random

@mlab.show
def image():
   mlab.imshow(random.random((10, 10)))

使用此装饰器,每次调用图像函数时,mlab 都会在执行图像函数之前确保正在运行交互式环境 。如果没有运行交互式环境,则mlab 将启动一个,并且在关闭图像功能之前,图像功能将不会返回。

动画数据

通常仅绘制数据是不够的。您可能还想更改图的数据并更新图,而不必重新创建整个可视化效果(例如制作动画或在交互式应用程序中)。实际上,重新创建整个可视化效果非常低效,并且会导致动画看起来非常生涩。为此,mlab提供了一种非常方便的方式来更改现有mlab可视化数据。考虑一个非常简单的例子。该mlab.test_simple_surf_anim功能有这样的代码:

import numpy as np
from mayavi import mlab
x, y = np.mgrid[0:3:1,0:3:1]
s = mlab.surf(x, y, np.asarray(x*0.1, 'd'))

for i in range(10):
    s.mlab_source.scalars = np.asarray(x*0.1*(i+1), 'd')

前两行定义一个简单的平面并对其进行查看。接下来的三行通过更改标量来生成一个围绕原点旋转的平面,从而对数据进行动画处理。这里的关键是上面的s对象具有一个称为mlab_source的特殊属性。这个子对象使我们可以操纵点和标量。如果我们想更改x值,也可以通过以下方式设置:

s.mlab_source.x = new_x

这里唯一要记住的是x的形状不应更改。

请注意,此处讨论的许多示例可能似乎根本没有动画,而您可能只是看到动画的最终状态。如果在动画的每个阶段保存图像的屏幕截图,您将获得正确的结果。但是,您将无法在屏幕上获得视觉效果。请参阅动画可视化部分, 以了解有关使用 @animate装饰器(mayavi.mlab.animate())的更多信息。我们在这里显示一个小示例,我们将上面的代码重写为动画效果:

import numpy as np
from mayavi import mlab
x, y = np.mgrid[0:3:1,0:3:1]
s = mlab.surf(x, y, np.asarray(x*0.1, 'd'))

@mlab.animate
def anim():
    for i in range(10):
        s.mlab_source.scalars = np.asarray(x*0.1*(i+1), 'd')
        yield

anim()
mlab.show()

在上面,请注意,我们将迭代包装在一个函数中,该函数是一个生成器,并使用@ mlab.animate装饰器对其进行装饰。

如果必须更改多个值,则可以使用mlab_source的set方法来设置它们,如下面更复杂的示例所示:

# Produce some nice data.
n_mer, n_long = 6, 11
pi = np.pi
dphi = pi/1000.0
phi = np.arange(0.0, 2*pi + 0.5*dphi, dphi, 'd')
mu = phi*n_mer
x = np.cos(mu)*(1+np.cos(n_long*mu/n_mer)*0.5)
y = np.sin(mu)*(1+np.cos(n_long*mu/n_mer)*0.5)
z = np.sin(n_long*mu/n_mer)*0.5

# View it.
l = mlab.plot3d(x, y, z, np.sin(mu), tube_radius=0.025, colormap='Spectral')

# Now animate the data.
ms = l.mlab_source
for i in range(10):
    x = np.cos(mu)*(1+np.cos(n_long*mu/n_mer +
                                      np.pi*(i+1)/5.)*0.5)
    scalars = np.sin(mu + np.pi*(i+1)/5)
    ms.trait_set(x=x, scalars=scalars)

注意上面set方法的使用。使用此方法,可视化仅重新计算一次。在这种情况下,新数组的形状没有改变,只有它们的值改变了。如果阵列的形状发生变化,则应使用复位方法,如下所示:

x, y = np.mgrid[0:3:1,0:3:1]
s = mlab.surf(x, y, np.asarray(x*0.1, 'd'),
              representation='wireframe')
# Animate the data.
fig = mlab.gcf()
ms = s.mlab_source
for i in range(5):
    x, y = np.mgrid[0:3:1.0/(i+2),0:3:1.0/(i+2)]
    sc = np.asarray(x*x*0.05*(i+1), 'd')
    ms.reset(x=x, y=y, scalars=sc)
    fig.scene.reset_zoom()

mlab提供了许多动画数据的标准示例。尝试使用名称为mlab.test_ _anim的示例,即名称以_anim结尾的示例,以查看它们如何工作和运行。

注意

 

记住set和reset之间的区别很重要。当您不更改数据形状而仅更改值时,请使用set或直接设置属性(x,y,标量等)。当阵列更改形状和大小时,请使用reset。重置通常会重新生成所有数据,与设置或直接设置特征相比可能效率低下。

警告

 

如以下小节所述,在创建Mayavi管道时,不使用现成的绘图功能,而 仅在通过mlab创建的源上创建mlab_source属性 。完全使用mlab创建的管道将显示此属性。

注意

 

如果要对多个打印对象设置动画,则每次使用mlab_source属性修改数据时,Mayavi都会触发场景刷新。此操作可能需要一些时间,因此会降低动画速度。在这种情况下,加速Mayavi脚本技巧 可能会派上用场。

用mlab组装管道

上面介绍的绘图功能仅探索Mayavi可视化功能的一小部分。Mayavi的全部功能只能通过管道本身的控制来释放。如Mayavi概述一节中所述,通过将Mayavi中的数据加载到数据源 对象中,然后通过Filters转换数据,并使用Modules将其可视化,来创建Mayavi中的可视化。mlab函数可以在一个函数中为您构建复杂的管道,从而正确选择了源,过滤器和模块,但是它们无法探索所有可能的组合。

Mlab提供了一个子模块管道,该子模块管道包含一些函数,这些函数可以从脚本轻松填充该管道。该模块可在mlab: mlab.pipeline中访问,也可以从mayavi.tools.pipeline导入 。

使用mlab绘图功能时,将创建管道:首先从numpy数组创建源,然后添加模块以及可能的过滤器。例如,可以使用mlab.show_pipeline命令查看生成的管道。此信息可用于直接使用管道脚本模块来创建完全相同的管道,因为创建管道的每个步骤所需的功能名称都直接链接到管道上mlab创建的对象的默认名称 。例如,让我们使用surf()以下内容创建可视化 :

import numpy as np
a = np.random.random((4, 4))
from mayavi import mlab
mlab.surf(a)
mlab.show_pipeline()

创建以下管道:

Array2DSource
    \__ WarpScalar
            \__ PolyDataNormals
                    \__ Colors and legends
                            \__ Surface

可以使用以下代码创建相同的管道:

src = mlab.pipeline.array2d_source(a)
warp = mlab.pipeline.warp_scalar(src)
normals = mlab.pipeline.poly_data_normals(warp)
surf = mlab.pipeline.surface(normals)

数据源

所述mlab.pipeline模块包含用于从阵列创建各种数据源的功能。它们在Mlab管道控制参考中有详细记录 。我们在这里简要介绍了各种可能性。

Mayavi可以区分具有标量数据的源和具有矢量数据的源 ,但更重要的是,它具有创建未连接点集(具有附加数据)或 描述可在数据点之间插值的连续变化量的连接数据点的不同功能,通常被称为域在物理或工程。

未连接的来源:
 
  • scalar_scatter()(创建一个PolyData)

    mlab:用于3D绘图的Python脚本_第17张图片
  • vector_scatter()(创建一个PolyData)

    mlab:用于3D绘图的Python脚本_第18张图片
隐式连接的源:
 
  • scalar_field()(创建一个ImageData)

    mlab:用于3D绘图的Python脚本_第19张图片
  • vector_field()(创建一个ImageData)

    mlab:用于3D绘图的Python脚本_第20张图片
  • array2d_source()(创建一个ImageData)

    mlab:用于3D绘图的Python脚本_第21张图片
显式连接的源:
 
  • line_source()(创建一个PolyData)

    mlab:用于3D绘图的Python脚本_第22张图片
  • triangular_mesh_source()(创建一个PolyData)

    mlab:用于3D绘图的Python脚本_第23张图片

所有mlab.pipline源工厂都是采用numpy数组并返回已添加到管道中的Mayavi源对象的函数。但是,隐式连接的源需要使用形状良好的数组作为参数:数据应该位于与输入数组的形状相同的规则的正交网格上,换句话说,数组描述的是图像,可能是3维的。

注意

 

可以创建更复杂的数据结构,例如不规则网格或非正交网格。请参阅 有关数据结构的部分。

模块和过滤器

对于每个Mayavi模块或过滤器(请参阅模块和过滤器),都有一个对应的mlab.pipeline函数。通过用下划线替换模块或过滤器名称中的大写字母来创建此函数的名称。因此,ScalarCutPlane对应于 scalar_cut_plane。

通常,mlab.pipeline模块和过滤器工厂函数仅创建并连接相应的对象。但是,它们也可以包含附加逻辑,这些附加逻辑作为关键字参数公开。例如,它们允许轻松地设置颜色图,或在相关时指定模块的颜色。为了使mlab界面简化日常操作的目标,他们使用关键字参数来选择所创建对象的属性以满足要求。因此,使用关键字参数(如果可用)可能比设置创建的对象的属性容易。有关更多信息,请查看文档字符串。下一节将提供完整,详细的用法示例。

一些可视化案例研究

可视化体积标量数据

可视化3D标量场的三种主要方法。给定以下字段:

import numpy as np
x, y, z = np.ogrid[-10:10:20j, -10:10:20j, -10:10:20j]
s = np.sin(x*y*z)/(x*y*z)
等值面:

要显示场的等值面,最简单的解决方案是使用mlab contour3d()函数:

mlab.contour3d(s)

mlab:用于3D绘图的Python脚本_第24张图片

这种方法的问题是外部等值面倾向于隐藏内部等值面。结果,通常只能看到一个等值面。

体积渲染:
 

体绘制是一种高级技术,其中为每个体素赋予部分透明的颜色。这可以通过 mlab.pipeline使用scalar_field()源代码和 卷模块来实现:

mlab.pipeline.volume(mlab.pipeline.scalar_field(s))

mlab:用于3D绘图的Python脚本_第25张图片

对于这种可视化,调整不透明度传递函数对于获得良好效果至关重要。通常,将下限值和上限值限制为数据的20%和80%很有用,以便使透明的体积的一部分合理:

mlab.pipeline.volume(mlab.pipeline.scalar_field(s), vmin=0, vmax=0.8)

mlab:用于3D绘图的Python脚本_第26张图片

打开模块的对话框(例如,通过管道接口,或使用其edit_traits()方法)并调整颜色传递函数以呈现图像的透明低强度区域,这很有用。对于此模块, 不使用颜色和图例” 节点中定义的LUT 

体绘制的局限性在于,尽管它通常很漂亮,但很难用它来分析字段的细节。

切平面:

切面虽然不那么令人印象深刻,但却是可视化标量场细节的非常有用的方法:

mlab.pipeline.image_plane_widget(mlab.pipeline.scalar_field(s),
                            plane_orientation='x_axes',
                            slice_index=10,
                        )
mlab.pipeline.image_plane_widget(mlab.pipeline.scalar_field(s),
                            plane_orientation='y_axes',
                            slice_index=10,
                        )
mlab.outline()

还可以使用以下mlab volume_slice()函数从NumPy数组中创建图像平面小部件:

mlab.volume_slice(s, plane_orientation='x_axes', slice_index=10)

mlab:用于3D绘图的Python脚本_第27张图片

图像平面窗口小部件只能用于由mlab.pipeline.scalar_field创建的规则间隔数据,但是它非常快。因此,在可能的情况下,应首选标量切割平面。

单击并拖动剖切面是探索该领域的绝佳方法。

技术组合:
 

最后,将等值线切割平面与等值线结合起来以使用等值曲面查看峰面积,用切割平面可视化场的细节以及具有较大等值线的整体质量可能会很有趣。表面:

src = mlab.pipeline.scalar_field(s)
mlab.pipeline.iso_surface(src, contours=[s.min()+0.1*s.ptp(), ], opacity=0.1)
mlab.pipeline.iso_surface(src, contours=[s.max()-0.1*s.ptp(), ],)
mlab.pipeline.image_plane_widget(src,
                            plane_orientation='z_axes',
                            slice_index=10,
                        )

mlab:用于3D绘图的Python脚本_第28张图片

在上面的示例中,我们使用mayavi的管道语法而不是使用contour3d()volume_slice() ,以便使用单个标量字段作为数据源。

在某些情况下,尽管在我们的示例中不是,但可以在切割平面之前插入阈值过滤器,例如:删除值小于's.min()+ 0.1 * s.ptp()'的区域。在这种情况下,剖切平面需要使用mlab.pipeline.scalar_cut_plane来实现,因为数据在阈值化之后会失去其结构。

可视化的矢量场

向量场,即在一个体积中连续定义的向量,可能难以可视化,因为它包含许多信息。让我们探索流体动力学中多轴对流池[1]的速度场的不同可视化,其定义为在网格u,v,w上采样的分量:

import numpy as np
x, y, z = np.mgrid[0:1:20j, 0:1:20j, 0:1:20j]

u =    np.sin(np.pi*x) * np.cos(np.pi*z)
v = -2*np.sin(np.pi*y) * np.cos(2*np.pi*z)
w = np.cos(np.pi*x)*np.sin(np.pi*z) + np.cos(np.pi*y)*np.sin(2*np.pi*z)
颤动:

一组向量的最简单可视化是使用mlab 函数quiver3d:

mlab.quiver3d(u, v, w)
mlab.outline()
mlab:用于3D绘图的Python脚本_第29张图片

这种可视化的主要局限性在于它为网格上的每个采样点定位了一个箭头。结果,可视化非常忙。

掩蔽向量:
 

我们可以利用这样的事实:我们正在可视化一个矢量场,而不仅仅是一堆矢量,以减少显示的箭头数量。为此,我们需要构建一个vector_field源,并向其应用带有一些屏蔽参数的 vectors模块(此处,我们只保留了20分之一):

src = mlab.pipeline.vector_field(u, v, w)
mlab.pipeline.vectors(src, mask_points=20, scale_factor=3.)
mlab:用于3D绘图的Python脚本_第30张图片
切面:

如果我们有兴趣沿切割显示矢量,则可以使用切割平面。特别是,我们可以通过沿以下方向移动切割平面来交互检查矢量场:单击并拖动它可以对矢量场有一个非常清晰的了解:

mlab.pipeline.vector_cut_plane(src, mask_points=2, scale_factor=3)
mlab:用于3D绘图的Python脚本_第31张图片
等值面:
 

向量场的重要参数是其大小。显示矢量法线的等值面可能很有趣。为此,我们可以使用ExtractVectorNorm过滤器从矢量字段创建标量字段,并在其上使用Iso-Surface模块。在交互工作时,可以通过在对象的属性对话框中更改轮廓的值来获得对场大小的良好理解。

magnitude = mlab.pipeline.extract_vector_norm(src)
mlab.pipeline.iso_surface(magnitude, contours=[1.9, 0.5])
mlab:用于3D绘图的Python脚本_第32张图片
流或字段线:
 

对于某些矢量场,沿该场的流线可能具有有趣的含义。例如,这可以解释为流体动力学的轨迹,或者电磁学中的磁力线。我们可以显示流线始发用于使用所述特定种子表面流模块,或者MLABflow()功能,这依赖于流线内部:

flow = mlab.flow(u, v, w, seed_scale=1,
                          seed_resolution=5,
                          integration_direction='both')
mlab:用于3D绘图的Python脚本_第33张图片
技术组合:
 

对矢量场进行有意义的可视化是一项艰巨的任务,并且必须使用手头的所有工具来说明其目的。选择传达的信息很重要。没有人可以看到所有关于矢量场的信息。这是通过组合上面的不同工具制成的可视化示例:

mlab.figure(fgcolor=(0., 0., 0.), bgcolor=(1, 1, 1))
src = mlab.pipeline.vector_field(u, v, w)
magnitude = mlab.pipeline.extract_vector_norm(src)

# We apply the following modules on the magnitude object, in order to
# be able to display the norm of the vectors, eg as the color.
iso = mlab.pipeline.iso_surface(magnitude, contours=[1.9, ], opacity=0.3)

vec = mlab.pipeline.vectors(magnitude, mask_points=40,
                                    line_width=1,
                                    color=(.8, .8, .8),
                                    scale_factor=4.)

flow = mlab.pipeline.streamline(magnitude, seedtype='plane',
                                        seed_visible=False,
                                        seed_scale=0.5,
                                        seed_resolution=1,
                                        linetype='ribbon',)

vcp = mlab.pipeline.vector_cut_plane(magnitude, mask_points=2,
                                        scale_factor=4,
                                        colormap='jet',
                                        plane_orientation='x_axes')
mlab:用于3D绘图的Python脚本_第34张图片

注意

 

尽管本节的大部分内容都集中在创建可视化对象的代码片段上,但重要的是要记住Mayavi是一个交互式程序,并且可以交互地修改这些对象的属性,如交互式更改对象属性中所述 。通常,事先无法为可视化选择最佳参数。颜色,轮廓值,颜色图,视角等应交互选择。如果需要再现性,则可以将所选值添加到原始脚本中。

此外,mlab函数仅展示可视化对象可能性的一小部分。对话框显示了更多这些功能,这些功能完全由mlab函数返回的对象的属性控制。这些对象非常丰富,因为它们是从VTK对象构建的。在浏览它们时或在VTK文档中可能很难找到要修改的正确属性,因此最简单的方法是使用管道视图对话框交互地修改它们,并使用记录功能找出相应的代码行。请参见 Mayavi可视化的组织:管道,以更好地理解由记录功能和mlab生成的代码行之间的链接 。。


[1] V. Toussaint;Carriere,P.和Raynal,F。一种通过混沌对流进行混合的数值欧拉方法。流体,1995,7,2587

你可能感兴趣的