Mayavi-更方便的可视化
10.1 用mlab快速绘图
和Chaco的shell或者matplotlib的pylab一样,mayavi的mlab模块提供了方便快捷的绘制三维图函 数。只要把数据准备好,通常只需要调用一次mlab的函数就可以看到数据的三维显示效果。非常适合 在IPython中交互式地使用。下面让我们来看一个例子:
import numpy as np
from enthought.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)
135
图 10.1 -使用Mayavi将二维数组绘制成3D曲面
我们先用下面的语句载入mlab库:
from enthought.mayavi import mlab
然后通过调用mlab.surf绘制一个三维空间中的曲面。曲面上的每个点的坐标由surf函数的三个二维数 组参数x,y,z给出。由于数组x,y是由ogrid对象算出,它们分别是shape为n*1和1*n的数组,而z是一个 n*n的数组。
通过调用mlab.axes和mlab.outline函数,分别在三维空间中添加坐标轴,和曲面区域的外框。
surf绘制的曲面在X-Y平面上的投影是一个等距离的网格,如果需要绘制更复杂的三维曲面的话,可以 使用mesh函数。下面是mesh函数的一个例子:
1 # coding: utf-8
-*-2 from numpy import *
3 from enthought.mayavi import mlab
4
5 # Create the data.
6 dphi, dtheta = pi/20.0, pi/20.0
7 [phi,theta] = mgrid[0:pi+dphi*1.5:dphi,0:2*pi+dtheta*1.5:dtheta]
8 m0 = 4; m1 = 3; m2 = 2; m3 = 3; m4 = 6; m5 = 2; m6 = 6; m7 = 4;
9 r = sin(m0*phi)**m1 + cos(m2*phi)**m3 + sin(m4*theta)**m5 + cos(m6*theta)**m7
10 x = r*sin(phi)*cos(theta)
11 y = r*cos(phi)
12 z = r*sin(phi)*sin(theta)
13
14 # View it.
15 s = mlab.mesh(x, y, z, representation="wireframe", line_width=1.0 )
136 第 10 章 Mayavi-更方便的可视化
用Python做科学计算
16
17 mlab.show()
图 10.2 -使用mesh函数绘制的3D旋转体
mesh和surf类似,其三个数组参数x, y, z也是二维数组,他们相同下标的三个元素组成曲面上某点的 三维坐标。点之间的连接关系(边和面)由其在x,y,z数组中间的位置关系决定。
由于这个程序所计算的曲面是一个旋转体,曲面上的各个点的坐标是在球面坐标系中计算的,然后按 照坐标转换公式将球面坐标转换为X-Y-Z坐标。
通过传递一个关键字参数representation给mesh函数,可以指定绘制的表现形式:
• surface : 缺省值,绘制曲面
• wireframe : 绘制边线,将dphi, dtheta的改为较大值,例如pi/20之后,调用 :
s = mlab.mesh(x, y, z, representation="wireframe", line_width=1.0 ) 得到如下结果:
图 10.3 -使用mesh函数绘制的线框模型
10.1. 用mlab快速绘图 137
为了方便理解mesh函数是如何绘制出曲面的,我们通过手工输入坐标的方式,绘制如下图所示的立方 体表面的一部分:
图 10.4 -组成立方体的各个面和顶点坐标
x,y,z数组的定义如下:
x = [[-1,1,1,-1,-1], [-1,1,1,-1,-1]]
y = [[-1,-1,-1,-1,-1], [1,1,1,1, 1]]
z = [[1,1,-1,-1,1], [1,1,-1,-1,1]]
x, y, z数组对应坐标的元素组成三维坐标点,因此这三个数组实际描述的坐标点为:
[
[(-1, -1, 1), (1, -1, 1), (1, -1, -1), (-1, -1, -1), (-1, -1, 1)]
[(-1, 1, 1), (1, 1, 1), (1, 1, -1), (-1, 1, -1), (-1, 1, 1)]
]
点之间的关系有其在数组中的下标决定,因此由:
(-1,-1,1),(1,-1,1),(-1,1,1),(1,1,1)
构成一个mesh中的一个面。依次类推,第二个面由:
138 第 10 章 Mayavi-更方便的可视化
用Python做科学计算
(1,-1,1),(1,-1,-1),(1,1,1),(1,1,-1)
构成,一共定义有4个面。
下面详细介绍mlab中提供的绘图函数。
• points3d, plot3d : 给它们传递的3个坐标数组x,y,z都是一维的,因此这两个函数绘制出来的是三 维空间中的一系列点(points3d),或者是一条曲线(plot3d)。下图是采用plot3d绘制的洛仑兹吸 引子的轨迹:
图 10.5 -plot3d函数绘制的洛仑兹吸引子,曲线使用很细的圆管绘制
绘图语句的程序如下:
mlab.plot3d(track1[:,0], track1[:,1], track1[:,2],color=(1,0,0), tube_radius=0.1)
其中track1为轨迹坐标数组,将其拆分为X,Y,Z轴的三个分量之后,传递给plot3d函数进行绘图。
tube_radius指定曲线的粗细,曲线实际上是采用极细的圆管绘制的。
洛仑兹吸引子的轨迹算法请参照:
SciPy-数值计算库
• imshow, surf, contour_surf : 这三个函数都可以接收一个二维数组s,以其第一轴的下标为X轴 坐标,第二轴的下标为Y轴坐标。imshow函数将此二维数组当作一个图片显示,每点的颜色为数 组s的每个元素的值。surf函数则将此二维数组绘制成三维空间中的曲面,数组中每个元素的值为 点的Z轴坐标。contour_surf则绘制二维数组的等高线。下面是imshow函数的绘制结果(所使用 的数组和前面surf函数的例子相同):
10.1. 用mlab快速绘图 139
图 10.6 -imshow函数将二维数组绘制成图像
同样的数据采用contour_surf函数绘制等高线的结果如下图所示:
图 10.7 -contour_surf函数绘制二维图像的等高线
140 第 10 章 Mayavi-更方便的可视化