这是上完中国MOOC《Pyhton计算计算三维可视化》的总结
课程url:here ,教师:黄天宇,嵩天
下文的图片和问题,答案都是从eclipse和上完课后总结的,转载请声明。
Python数据三维可视化
1. Introduction
1.1. 可视化计算工具
- · TVTK 科学计算三维可视化基础
Mayavi 三维网格面绘制,三维标量场和矢量场绘制
TraitsUI 交互式三维可视化
SciPy 拟合,线性差值,统计,插值
数据过滤器
需要安装的软件:VTK, Mayavi, numpy, PyQt4, Traits, TraitsUI
1.2. 内容组织
流体数据的标量可视化、矢量可视化实例
三维扫描数据(模型/地形)
三维地球场景可视化实例
曲线UI交互控制可视化
2. 基础运用
2.1. TVTK入门
科学计算可视化主要方法
- 二维标量数据场:颜色映射法,等值线法,立体图/层次分割法
- 三维标量数据场:面绘制法,体绘制法
- 矢量数据场:直接法,流线法
下载python开源库网站:https://www.lfd.uci.edu/~gohlke/pythonlibs/ 这里基本上集成了python需要用到的各个库的资源。
VTK库安装方法是将文件放在<C:\WINDOWS\system32>下面,这样系统可以自动检测到并安装,安装在使用如下操作,在开始菜单栏,输入cmd,用管理员身份启动cmd,输入pip install xxx(VTK版本号),有时候安装不行是因为pip需要更新,或者VTK文件放的位置不对,只要根据系统提示正确操作就行。
2.2. 创建一个基本三维对象
tvtk.CubeSource()的使用代码为s = tvtk.CubeSource(traits)
tvtk中CubeSource()的调用方式:
s = tvtk.CubeSource(x_length=1.0,y_length=2.0,z_length=3.0)
- · x_length:立方体在X轴的长度
- · y_length:立方体在Y轴的长度
- · z_length:立方体在Z轴的长度
以下是s的输出结果:
Debug: Off
Modified Time: 1903583
Reference Count: 2
Registered Events:
Registered Observers:
vtkObserver (000001813DFDB520)
Event: 33
EventName: ModifiedEvent
Command: 000001813DBFDF80
Priority: 0
Tag: 1
Executive: 000001813D838460
ErrorCode: No error
Information: 000001813D864210
AbortExecute: Off
Progress: 0
Progress Text: (None)
X Length: 1
Y Length: 2
Z Length: 3
Center: (0, 0, 0)
Output Points Precision: 0
- · 可以用s.x_length/s.y_length/s.z_length获取长方体在三个方向上的长度。
- · CubeSource对象的方法
方法 |
说明 |
Set/get_x_length() |
设置/获取长方体对象在X轴方向的长度 |
Set/get_y_length() |
设置/获取长方体对象在Y轴方向的长度 |
Set/get_z_length() |
设置/获取长方体对象在Z轴方向的长度 |
Set/get_center() |
设置/获取长方体对象所在坐标系的原点 |
Set/get_bounds() |
设置/获取长方体对象的包围盒 |
TVTK库的基本三维对象
三维对象 |
说明 |
CubeSource |
立方体三维对象数据源 |
ConeSource |
圆锥三维对象数据源 |
CylinderSource |
圆柱三维对象数据源 |
ArcSource |
圆弧三维对象数据源 |
ArrowSource |
箭头三维对象数据源 |
比如建立圆锥model,输入
from tvtk.api import tvtk
s = tvtk.ConeSource(height=3.0,radius=1.0,resolution=36)
可以用s.height/s.radius/s.resolution(分辨率)查到高度,半径和分辨率的数据,如果要详细指导所有数据,可以用print(s)命令。
vtkConeSource (000001813DE1E0E0)
Debug: Off
Modified Time: 1903620
Reference Count: 2
Registered Events:
Registered Observers:
vtkObserver (000001813DFDC000)
Event: 33
EventName: ModifiedEvent
Command: 000001813DBFDD40
Priority: 0
Tag: 1
Executive: 000001813D839090
ErrorCode: No error
Information: 000001813D864120
AbortExecute: Off
Progress: 0
Progress Text: (None)
Resolution: 36
Height: 3
Radius: 1
Capping: On
Center: (0, 0, 0)
Direction: (1, 0, 0)
Output Points Precision: 0
2.3. 显示一个基本三维对象
2.3.1. 如何利用tvtk绘制三维图形
tvtk使用管线(pipeline)绘制三维图形,其中一下函数
CubeSource(xxx)
PolyDataMapper(xxx)
Actor(xxx)
Renderer(xxx)
RenderWindow(xxx)
RenderWindowInteracotor(xxx)
协作完成管线任务
2.3.2. 实现一个三维长方体代码
代码例1
from tvtk.api import tvtk
s = tvtk.CubeSource(x_length=1.0,y_length=2.0,z_length=3.0)
m = tvtk.PolyDataMapper(input_connection = s.output_port)
a = tvtk.Actor(mapper=m)
r = tvtk.Renderer(background=(0,0,0))
r.add_actor(a)
w = tvtk.RenderWindow(size=(300,300))
w.add_renderer(r)
i = tvtk.RenderWindowInteractor(render_window = w)
i.initialize()
i.start()
2.4. TVTK管线与数据加载
- · TVTK管线分两部分:数据预处理和图形可视化
- · 数据预处理以s.output_port和m.input_connection形式输出
- · 管线的两种类型:可视化管线(将原始数据加工成图形数据),图形管线(图形数据加工成图像)
- · 可视化管线分两个对象:PolyData(计算输出一组长方形数据)和PolyDataMapper(通过映射器映射为图形数据)
TVTK对象 |
说明 |
Actor |
场景中一个实体,描述实体位置,方向,大小的属性 |
Renderer |
渲染作用,包括多个Actor |
RenderWindow |
渲染用的图形窗口,包括一个或多个Render |
RenderWindowInteractor |
交互功能,评议,旋转,放大缩小,不改变Actor或数据属性,只调整场景中照相机位置 |
- · 管线的数据可以表示如下:
- · 总结下TVTK管线就分为以下几个部分:数据预处理,数据映射,图形绘制,图形显示与交互
- · 建立长方形模型:
2.4.1. IVTK观察管线
代码例2
from tvtk.api import tvtk from tvtk.tools import ivtk from pyface.api import GUI s = tvtk.CubeSource(x_length=1.0,y_length=2.0,z_length=3.0) m = tvtk.Actor(mapper=m) gui = GUI() win = ivtk.IVTKWithCrustAndBrowser() win.open() True win.scene.add_actor(a) gui.start_event_loop()
显示结果:
有会出现bug,在主窗口缩放时左侧串口处于游离状态。
Debug程序:
from tvtk.api import tvtk from tvtk.tools import ivtk from pyface.api import GUI s = tvtk.CubeSource(x_length=1.0,y_length=2.0,z_length=3.0) m = tvtk.PolyDataMapper(input_connection=s.output_port) a = tvtk.Actor(mapper=m) gui = GUI() win = ivtk.IVTKWithCrustAndBrowser() win.open() win.scene.add_actor(a) dialog = win.control.centralWidget().widget(0).widget(0) from pyface.qt import QtCore dialog.setWindowFlags(QtCore.Qt.WindowFlags(0x00000000)) dialog.show() gui.start_event_loop()
Debug后第窗口界面,注意左侧的菜单栏,有分级
Model 建立后,可以在命令框输入代码,获取数据,比如:
输入print(scene.renderer.actors[0].mapper.input.points.to_array),可以得到长方体各个顶点的坐标。
如果要集成开发,可以将函数单独封装,放到python.exe目录下,比如上一个生成长方体的代码可以封装成以下两部分:
主函数
from tvtk.api import tvtk from tvtkfunc import ivtk_scene,event_loop s = tvtk.CubeSource(x_length=1.0,y_length=2.0,z_length=3.0) m = tvtk.PolyDataMapper(input_connection=s.output_port) a = tvtk.Actor(mapper=m) win = ivtk_scene(a) win.scene.isometric_view() event_loop()
调用函数
def ivtk_scene(actors): from tvtk.tools import ivtk # 创建一个带Crust(Python Shell)的窗口 win = ivtk.IVTKWithCrustAndBrowser() win.open() win.scene.add_actor(actors) # 修正窗口错误 dialog = win.control.centralWidget().widget(0).widget(0) from pyface.qt import QtCore dialog.setWindowFlags(QtCore.Qt.WindowFlags(0x00000000)) dialog.show() return win def event_loop(): from pyface.api import GUI gui = GUI() gui.start_event_loop()
2.4.1. Tvtk数据集(TVTK数据加载例1)
Tvtk中有5中数据集:
- · ImageData表示二维/三维图像的数据结构,有三个参数,spacing,origin,dimensions
from tvtk.api import tvtk img = tvtk.ImageData(spacing=(1,1,1),origin=(1,2,3),dimensions=(3,4,5)) img.get_point(0) #attain the data of first point (1.0, 2.0, 3.0) for n in range(6): ... print("%1.f,%1.f,%1.f"%img.get_point(n))
最后得到结果
1,2,3
2,2,3
3,2,3
1,3,3
2,3,3
3,3,3
- · RectilinearGrid 表示创建间距不均匀的网格,所有点都在正交的网格上通过如下代码构建数据集:
r.y_coordinates = y r.z_coordinates = z r.dimensions = len(x),len(y),len(z) r.x_coordinates = x r.y_coordinates = y r.z_coordinates = z r.dimensions = len(x),len(y),len(z) for n in range(6): ... print(r.get_point(n))
得到数据结果,在轴上数据递增:
(0.0, 0.0, 0.0)
(3.0, 0.0, 0.0)
(9.0, 0.0, 0.0)
(15.0, 0.0, 0.0)
(0.0, 1.0, 0.0)
(3.0, 1.0, 0.0)
- · StructuredGrid 表示创建任意形状网格,需要指定点的坐标
- · PolyData 表示由一系列的点、点之间的联系以及由点构成的多边形组成
- · UnstructuredGrid 无组织网格
TVTK数据集 |
特点 |
Imagedata |
正交等间距 |
RectilinearGrid |
正交不等间距 |
StructuredGrid |
任意形状网格 |
PolyData |
点和点之间的联系 |
UnstructuredGrid |
无组织点 |
2.4.3. Tvtk读取stl文件
STL文件调用形式:
S = tvtk.STLReader(file_name = “stl文件名”)
文件调用形式
vtkOBJReader()
ply文件调用形式
vtkPLYReader()
调用外部数据
VtkMultiBlockPLOT3DReander()
from tvtk.api import tvtk from tvtkfunc import ivtk_scene,event_loop s = tvtk.STLReader(file_name = 'python.stl') m = tvtk.PolyDataMapper(input_connection = s.output_port) a = tvtk.Actor(mapper=m) win = ivtk_scene(a) win.scene.isometric_view() event_loop()
Stl格式数据,可以在python三维可视化中打开,也就是说solidworks中创建的stl文件也可以在python三维可视化中打开。
2.4.4. Tvtk读取MultiBlock3D数据文件
3D文件读取用MultiBlock数据读取。
网格(XYZ文件),空气动力学结果(Q文件),通用结果文件
源码:但是执行失败,错误类型是tvtk没有定义,或者plot3d没有定义
1. from tvtk.api import tvtk 2. 3. def read_data():# 读入数据 4. plot3d = tvtk.MultiBlockPLOT3DReader( 5. xyz_file_name="combxyz.bin",#网格文件 6. q_file_name="combq.bin",#空气动力学结果文件 7. scalar_function_number=100,#设置标量数据数量 8. vector_function_number=200#设置矢量数据数量 9. ) 10. plot3d.update() 11. return plot3d 12. 13. plot3d = read_data() 14. grid = plot3d.output.get_block(0)
3. VTK可视化基础实战
介绍三类可视化方法:标量可视化,矢量可视化,轮廓化可视化
3.1. 可视化实例
3.1.1. 标量可视化
等值面:标量值相等的面
Generate_value() 设定N条等值线的值,一般用于重新绘制等值线
Set_value() 设定一条等值线的值,一般用于覆盖某条等值线或者新增加一条等值线
代码例2:绘制流体数据模型的标量场
from tvtk.api import tvtk from tvtkfunc import ivtk_scene,event_loop plot3d = tvtk.MultiBlockPLOT3DReader( ... xyz_file_name="combxyz.bin", ... q_file_name="combq.bin", ... scalar_function_number=100,vector_function_number=200) plot3d.update() grid=plot3d.output.get_block(0) con = tvtk.ContourFilter() con.set_input_data(grid) con.generate_values(20,grid.point_data.scalars.range) m = tvtk.PolyDataMapper(scalar_range=grid.point_data.scalars.range,input_connection=con.output_port) a = tvtk.Actor(mapper=m) a.property.opacity=0.5 win = ivtk_scene(a) #以下3行为交互代码 win.scene.isometric_view() event_loop()
Generate_values(x,y)两个参数意义:x代表指定轮廓数,y代表数据范围
同样set_values(x,y)中也有同样的两个参数,含义相同,改变这两个参数会改变轮廓数和数据范围
3.1.2. 矢量可视化
Tvtk.Glyph3D() 符号化技术,可以解决矢量数据可视化问题。
Tvtk.MaskPoints() 降采样
箭头表示标量大小,箭头方向表示矢量方向。
代码例3 矢量化向量
from tvtk.api import tvtk from tvtkfunc import ivtk_scene,event_loop plot3d = tvtk.MultiBlockPLOT3DReader( ... xyz_file_name = "combxyz.bin", ... q_file_name = "combq.bin", ... scalar_function_number = 100,vector_function_number = 200) plot3d.update() grid = plot3d.output.get_block(0) mask = tvtk.MaskPoints(random_mode=True,on_ratio=50) mask.set_input_data(grid) glyph_source = tvtk.ConeSource() glyph = tvtk.Glyph3D(input_connection=mask.output_port,scale_factor=4) glyph.set_source_connection(glyph_source.output_port) m = vtk.PolyDataMapper(scalar_range=grid.point_data.scalars.range,input_connection=glyph.output_port) a = tvtk.Actor(mapper = m) win = ivtk_scene(a) win.scene.isometric_view() event_loop()
得到结果:
- · Tvtk.Glyph3D() 符号化技术
为了表示矢量数据,TVTK库中运用tvtk.Glyph3D()方法,同时运用MaskPoints()方法进行降维采样。
3.1.3. 空间轮廓线可视化
需要用到tvtk.StructuredGridOutlineFilter()
Python清空命令行代码函数:
Import os def clear(): os.system(‘cls’) clear()
代码例4
from tvtk.api import tvtk from tvtk.common import configure_input from tvtkfunc import ivtk_scene, event_loop plot3d = tvtk.MultiBlockPLOT3DReader( xyz_file_name="combxyz.bin", q_file_name="combq.bin", scalar_function_number=100, vector_function_number=200 )#读入Plot3D数据 plot3d.update()#让plot3D计算其输出数据 grid = plot3d.output.get_block(0)#获取读入的数据集对象 outline = tvtk.StructuredGridOutlineFilter()#计算表示外边框的PolyData对象 configure_input(outline, grid)#调用tvtk.common.configure_input() m = tvtk.PolyDataMapper(input_connection=outline.output_port) a = tvtk.Actor(mapper=m) a.property.color = 0.3, 0.3, 0.3 #窗口绘制 win = ivtk_scene(a) win.scene.isometric_view() event_loop()
显示结果
- · PolyData对象的外边框处理使用了什么方法?
PolyData对象外边框使用了StructuredGridOutlineFilter()的方法。
3.1.4. 结合矢量可视化和空间轮廓线可视化
对标量/轮廓属性进行赋值,不会处理。
from tvtk.api import tvtk from tvtk.common import configure_input from tvtkfunc import ivtk_scene, event_loop plot3d = tvtk.MultiBlockPLOT3DReader( ... xyz_file_name = "combxyz.bin", ... q_file_name = "combq.bin", ... scalar_function_number = 100,vector_function_number = 200) plot3d.update() grid = plot3d.output.get_block(0) con = tvtk.ContourFilter() con.set_input_data(grid) con.generate_values(20,grid.point_data.scalars.range) #20代表等值面 outline = tvtk.StructuredGridOutlineFilter()#计算表示外边框的PolyData对象 configure_input(outline, grid)#调用tvtk.common.configure_input() m = tvtk.PolyDataMapper(scalar_range=grid.point_data.scalars.range,input_connection=con.output_port) m = tvtk.PolyDataMapper(input_connection=outline.output_port) a = tvtk.Actor(mapper=m) a.property.color = 0.3, 0.3, 0.3 a.property.opacity=0.5 win = ivtk_scene(a) #以下3行为交互代码 win.scene.isometric_view() event_loop()
3.2. TVTK库实战练习
- 练习1:用tvtk绘制一个圆锥,圆锥的数据源对象为ConeSource(),圆锥高度为6.0,圆锥半径为2.0,背景色为红色。
代码例5
from tvtk.api import tvtk from tvtk.tools import ivtk from pyface.api import GUI s = tvtk.ConeSource(height=6.0,radius=1.0,resolution=36) m = tvtk.PolyDataMapper(input_connection=s.output_port) a = tvtk.Actor(mapper=m) gui = GUI() win = ivtk.IVTKWithCrustAndBrowser() win.open() win.scene.add_actor(a) dialog=win.control.centralWidget().widget(0).widget(0) from pyface.qt import QtCore dialog.setWindowFlags(QtCore.Qt.WindowFlags(0x00000000)) dialog.show() gui.start_event_loop()
代码例6
from tvtk.api import tvtk s = tvtk.ConeSource(height=6.0,radius=2.0,resolution=36) m = tvtk.PolyDataMapper(input_connection=s.output_port) a = tvtk.Actor(mapper=m) r = tvtk.Renderer(background=(1,0,0)) r.add_actor(a) w = tvtk.RenderWindow(size=(300,300)) w.add_renderer(r) i = tvtk.RenderWindowInteractor(render_window=w) i.initialize() i.start()
- 练习2:使用tvtk库读取obj,并显示出来。
from tvtk.api import tvtk from tvtkfunc import ivtk_scene,event_loop s = tvtk.OBJReader(file_name = 'python.obj') m = tvtk.PolyDataMapper(input_connection = s.output_port) a = tvtk.Actor(mapper=m) win = ivtk_scene(a) win.scene.isometric_view() event_loop()
- x.obj文件应该放在anaconda(python)安装目录下。
- Stl和obj模型包括哪些信息?
Stl全称是stereolithograph,模型包括三角面片数,每个三角面片的几何信息(法矢,三个顶点的坐标),三角面片属性。
Obj是3D模型文件模式,模型包括顶点数据,自由形态曲线/表面属性,元素,自由形态曲线/表面主题陈述,自由形态表面之间的连接,成组,显示/渲染属性。
- 练习3:通过get_value()和set_value()设定第一个等值面的值为原来的2倍
3.3. Mayavi库入门
类别 |
说明 |
绘图函数 |
Barchar, contour3d, contour_surf, flow, imshow, mesh, plot3d, points3d, quiver3d, surf, triangular, mesh |
图形控制函数 |
Clf, close, draw, figure, fcf, savefig, screenshot, sync_camera |
图形修饰函数 |
Colorbar, scalarbar, xlabel, ylabel, zlabel |
相机控制函数 |
Move, pitch, roll, view, set_engine |
其他函数 |
Animate, axes, get_engine, show, set_engine |
Mlat管线控制 |
Open, set_tvk_src,adddataset, scalar_cut_plane |
Mayavi API
类别 |
说明 |
管线基础对象 |
Scene, source, filter, modulemanager, module, pipelinebase, engine |
主视窗和UI对象 |
DecoratedScene, mayaviscene, sceneeditor, mlabscenemodel, engineview, enginerichview |
3.3.1. 快速绘图实例
代码例7
#定义10个点的三维坐标,建立简单立方体
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]] from mayavi import mlab s = mlab.mesh(x,y,z)
代码例8
#建立复杂几何体
From numpy import pi,sin,cos,mgrid from mayavi import mlab 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) s = mlab.mesh(x,y,z) mlab.show()
Mesh函数是三个二维的参数,点之间的连接关系,尤其由x,y,z之间的位置关系所决定。
上面这个例子如果改变代码行为mlab.mesh(x,y,z,representation="wireframe",line_width=1.0)
则结果为
3.3.2. Mayavi管线(分析mayavi如何控制画面)
Mayavi管线的层级
- Engine:建立和销毁Scenes
- Scenes:多个数据集合Sources
- Filters:对数据进行变换
- Modules Manager:控制颜色,Colors and Legends
- Modules:最终数据的表示,如线条、平面等
程序配置属性的步骤:
- 获得场景对象,mlab.gcf()
- 通过children属性,在管线中找到需要修改的对象
配置窗口有多个选项卡,属性需要一级一级获得
s = mlab.gcf #获得s对象当前场景 print(s) #输出当前对象状态 print(s.scene.background) #输出当前设置的场景的背景色 source = s.children[0] #获取对象 print(repr(source)) #输出mlab儿子数组对象的第一个值地址 print(source.name) #返回该节点名称 print(repr(source.data.points)) #输出该节点坐标 print(repr(source.data.point_data.scalars)) manager = source.children[0] #数据源法向量 print(manager) #通过程序更改物体颜色和对应颜色值 colors = manager.children[0] colors.scalar_lut_manager.show_legend = True surface = colors.children[0] #获取颜色的第一个子节点。Surface可以设置图形的显示方式 surface.actor.property.representation = “wireframe” surface.actor.property.opacity = 0.6 #透明度设置为0.6
mayavi与tvtk处理三维可视化的异同点:tvtk处理三维可视化要通过映射,预处理步骤,而mayavi在获取数据,可以通过mlab.mesh(x,y,z)生成三维可视化图形。
3.4. Mayavi库入门
3.4.1. 基于numpy数组的绘图函数
- · Mlab对numpy建立可视化过程:
- 建立数据源
- 使用filter(可选)
- 添加可视化模块
3D绘图函数-Points3d()
- · 函数形式:
Points3d(x,y,z,…) points3d(x,y,z,s,...) points3d(x,y,z,f,…)
X,y,z便是numpy数组、列表或者其他形式的点三维坐标
s表示在该坐标点处的标量值
F表示通过函数f(x,y,z)返回的标量值
代码例9
t = np.linspace(0, 4 * np.pi, 20) x = np.sin(2 * t) y = np.cos(t) z = np.cos(2 * t) s = 2 + np.sin(t) points = mlab.points3d(x,y,z,s,colormap='Reds',scale_factor=.25)
参数 |
说明 |
Color |
VTK对象的颜色,定义为(0,1)的三元组 |
Colormap |
Colormap的类型,例如Reds、Blues、Copper等 |
Extent |
x,y,z数组范围[xmin,xmax,ymin,ymax,zmin,zmax] |
Figure |
画图 |
Line_width |
线的宽度,该值为float,默认为0.2 |
Mask_points |
减小/降低大规模点数据集的数量 |
Mode |
符号的模式,例如2darrow、2dcircle、arrow、cone等 |
Name |
VTK对象名字 |
Opcity |
VTK对象的整体透明度,改值为float型,默认为1.0 |
Reset_zoom |
对新加入场景数据的缩放进行重置。默认为True |
Resolution |
符号的分辨率,如球体的细分数,该值为整型,默认为8 |
Scale_factor |
符号放缩的比例 |
Scale_mode |
符号的放缩模式,如vector、scalar、none |
Transparent |
根据标量值确定actor的透明度 |
Vmax |
对colormap放缩的最大值 |
Vmin |
对colormap放缩的最小值 |
- · 3D绘图函数-Plot3d()
函数形式:
Plot3d(x,y,z…) plot3d(x,y,z,s,…)
X,y,z表示numpy数组,或列表。给出了线上连续的点的位置。S表示在该坐标点处的标量值
参数 |
说明 |
Tube_radius |
线管的半径,用于描述线的粗细 |
Tube_sides |
表示线的分段数,该值为整数,默认为6 |
X,y,z表示numpy数组,给出了线上连续的点的位置。
Np.sin(mu)表示在该坐标点处的标量值
Tube_radius绘制线的半径为0.025
Colormap采用Spectral颜色模式
代码例10
import numpy as np from mayavi import mlab n_mer, n_long = 6,11 dphi = np.pi / 1000.0 phi = np.arange(0.0, 2 * np.pi + 0.5 * dphi, dphi) 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 l = mlab.plot3d(x,y,z,np.sin(mu),tube_radius=0.025,colormap="Spectral")
X,y,z便是numpy数组,给出了线上连续的点的位置。
Np.sin(mu)表示在该坐标点处的标量值
Tube_radius绘制线的半径为0.025
Colormap采用Spectral颜色模式
- · 3D绘图函数-2D数据
Imshow()-3D绘图函数
Interpolate 图像中的像素是否被插值,该值为布尔型,默认为True
代码例11
import numpy from mayavi import mlab s = numpy.random.random((10,10)) img = mlab.imshow(s,colormap='gist_earth') mlb.show()
3D绘图函数 - surf()
函数形式:
Surf(s,...)
Surf(x,y,s…)
Surf(x,y,f,..)
S是一个高程矩阵,用二维数组表示
代码例12
import numpy as np from mayavi improt mlab from mayavi import mlab def f(x,y): return np.sin(x - y) + np.cos(x + y) x, y = np.mgrid[-7.:7.05:0.1,-5.:5.05:0.05] s = mlab.surf(x,y,f) mlab.show()
3D绘制函数 - contour_surf(),与surf()类似求解曲面,contour_surf求解等值线
代码例13
import numpy as np from mayavi import mlab def f(x,y): return np.sin(x - y) + np.cos(x + y) x,y = np.mgrid[-7.:7.05:0.1,-5.:5.05:0.05] con_s = mlab.contour_surf(x,y,f)
3D绘图函数 - contour3d()
函数形式:
Contour3D(scalars…)
Contour3d(x,y,z,scalar,..)
Scalars 网络上的数据,用三维numpy数组shuming,x,y,z代表三维空间坐标
参数 |
说明 |
Contours |
定义等值面的数量 |
代码例14
import numpy from mayavi import mlab x,y,z = numpy.ogrid[-5:5:64j,-5:5:64j,-5:5:64j] scalars = x * x + y * y + z * z obj = mlab.contour3d(scalars, contours=8,transparent=True)
3D绘图函数 – quiver3d()
函数形式:
quiver3d(u,v,w…)
quiver3d(x,y,z,u,v,w…)
quiver3d(x,y,z,f,…)
u,v,w用numpy数组表示的向量
x,y,z表示箭头的位置,u,v,w矢量元素
f需要返回咋给定位置(x,y,z)的(u,v,w)矢量
代码例15
r = np.sqrt(x ** 2 + y ** 2 + z ** 4) u = y * np.sin(r) / (r + 0.001) v = -x * np.sin(r)/ (r + 0.001) w = np.zeros_like(z) obj = mlab.quiver3d(x,y,z,u,v,w,line_width=3,scale_factor=1)
Questions:
- points3D和Plot3D两个函数之间的区别于联系是什么?
- Imshow()方法是如何确定二维数组可视化图像颜色的?
- Surf()方法实例中通过什么方法获取x,y二维数组的?
- Mlab中可以进行矢量数据可视化的方法有哪些?
Corresponding answers:
- Points3D是基于Numpy数组x,y,z提供的数据点坐标,绘制图形;Plot3D是基于1维numpy数组x,y,z供的三维坐标数据绘制图形;
- Imshow()通过colormap关键字确定颜色,比如colormap='gist_earth',确定颜色为“类似地球表面颜色”;
- Surf()方法是通过np.mgrid(xxx,xxx)获取x,y二维数组;
- mlab.Flow()和mlab.quiver3d()
3.4.2. 改变物体的外观
- · 改变颜色
代码例16
Colormap定义的颜色,也叫LUT即look up table.
import numpy as np from mayavi import mlab x,y = np.mgrid[-10:10:200j,-10:10:200j] z = 100 * np.sin(x * y) / (x * y) mlab.figure(bgcolor=(1,1,1)) <mayavi.core.scene.Scene object at 0x00000214003D6678> surf = mlab.surf(z,colormap='cool') mlab.show()
代码例17
当代码例16增加以下代码到代码例17时,图像的颜色变淡,透明度增加。
import numpy as np from mayavi import mlab #建立数据 x,y = np.mgrid[-10:10:200j,-10:10:200j] z = 100 * np.sin(x * y) / (x * y) #对数据进行可视化 mlab.figure(bgcolor=(1,1,1)) <mayavi.core.scene.Scene object at 0x00000214003D6678> surf = mlab.surf(z,colormap='cool') mlab.show() #访问surf对象的LUT #LUT是一个255x4的数组,列向量表示RGBA,每个值的范围从0-255 lut = surf.module_manager.scalar_lut_manager.lut.table.to_array() #增加透明度,修改alpha通道 lut[:,-1] = np.linspace(0,255,256) surf.module_manager.scalar_lut_manager.lut.table = lut #更新视图,并显示图像 mlab.show()
3.4.3. Mlab控制函数
图像控制函数:
函数图像 |
说明 |
Clf |
清空当前图像mlab.clf(figure=None) |
close |
关闭图形窗口 mlab.close(scene=None, all=False) |
Draw |
重新绘制当前图像mlab.close(figure=None) |
Figure |
建立一个新的scene或者访问一个存在的scene mlab.figure(figure=None,bgcolor=None,fgcolor=None,engine=None,size=(400,350)) |
Gcf |
返回当前图像的handle mlab.gcf(figure=None) |
Savefig |
存储当前的前景,输出为一个文件,如png,jpg,bmp,tiff,pdf,obj,vrml等 |
图像装饰函数
函数图像 |
说明 |
Cololorbar |
为对象的颜色映射增加颜色条 |
Scalarbar |
为对象的标量颜色映射增加颜色条 |
Vectorbar |
为对象的矢量颜色映射增加颜色条 |
xlabel |
建立坐标轴,并添加x轴的标签mlab.xlabel(text,object=None) |
Ylabel |
建立坐标轴,并添加y轴的标签 |
zlabel |
建立坐标轴,并添加z轴的标签 |
相机控制函数
函数图像 |
说明 |
Move |
移动相机和焦点 Mlab.move(forward=None,right=None,up=None) |
Pitch |
沿着“向右”轴旋转角度mlab.pitch(degrees) |
View |
设置/获取当前视图中相机的视点 Mlab.view(azimuth=None,elevation=None,distance=None,focalpoint=None,roll=None Reset_roll=True,figure=None |
Yaw |
沿着“向上”轴旋转一定角度,mlab.yaw(degrees) |
其他控制函数
函数图像 |
说明 |
animate |
动画控制函数mlab.animate(func=None,delay=500,ui=True) |
Axes |
为当前物体设置坐标轴mlab.axes(*args,**kwargs) |
Outline |
为当前物体建立外轮廓mlab.outline(*args,**kwargs) |
Show |
与当前图像开始交互mlab.show(func=None,stop=False) |
Show_pipeline |
显示mayavi的管线对话框,可以进行场景属性的设置和编辑 |
Text |
为图像添加文本mlab.text(*args,**kwargs) |
Title |
为绘制图像建立标题mlab.title(*args,**kwargs) |
3.4.4. 鼠标选取交互操作
On_mouse_pick(callback,type=”point”,Button=”left”,Remove=False)提供鼠标响应操作
Type:”point”,”cell” or “world”
Button:”Left”,”Middle” or “Right”
Remove:如果值为True,则callback函数不起作用
返回:一个vtk picker对象
代码例18
程序框架:
#场景初始化 figure = mlab.gcf() #用mlab.points3d建立红色和白色小球的集合 # … … #处理选取事件 def picker_callback(picker) #建立响应机制 Picker = figure.on_mouse_pick(picker_callback) mlab.show() import numpy as np from mayavi import mlab figure = mlab.gcf() x1, y1, z1 = np.random.random((3, 10)) red_glyphs = mlab.points3d(x1, y1, z1, color=(1, 0, 0), resolution=10) x2, y2, z2 = np.random.random((3, 10)) white_glyphs = mlab.points3d(x2, y2, z2, color=(0.9, 0.9, 0.9), resolution=10) outline = mlab.outline(line_width=3) outline.outline_mode = 'cornered' outline.bounds = (x1[0] - 0.1, x1[0] + 0.1, y1[0] - 0.1, y1[0] + 0.1, z1[0] - 0.1, z1[0] + 0.1) glyph_points = red_glyphs.glyph.glyph_source.glyph_source.output.points.to_array() def picker_callback(picker): if picker.actor in red_glyphs.actor.actors: point_id = int(picker.point_id / glyph_points.shape[0]) if point_id != -1: x, y, z = x1[point_id], y1[point_id], z1[point_id] outline.bounds = (x - 0.1, x + 0.1, y - 0.1, y + 0.1, z - 0.1, z + 0.1) picker = figure.on_mouse_pick(picker_callback) mlab.title('Click on red balls') mlab.show()
简述选取红色小球问题分析实例程序的基本框架和搭建流程。
1.绘制初始状态选取框时,为什么数组下标为0?
2.实例中是如何计算被获取的红色小球的位置坐标的?
3.实例程序优化中是如何解决小球初始化速度太慢的问题的
Answers:
基本框架:初始化场景-建立小球模型-处理响应事件(建立立方体套框模型)-建立响应机制(把框套到球上)
1. 绘制初始状态选取框时,希望放在第一个球上
2. 同过一下代码:
glyph_points = red_glyphs.glyph.glyph_source.glyph_source.output.points.to_array()
3. Before drawing the object add the code of figure.scene.disable_render = True, and after drawing the object add the code of figure.scene.disable_render = False
In the phase of creating response mechanism, add the code of Picker.tolerance = 0.01 after picker = xxx
3.4.5. Mlab控制函数(23 module函数)
Mlab管线控制函数的调用
Sources: 数据源
Filters: 用来数据变换
Modules: 用来实现可视化
mlab.pipeline.function()
Sources
Grid_source |
建立而为网络数据 |
Line_source |
建立线数据 |
Open |
打开一个数据文件 |
scalar_field |
建立标量场数据 |
Vector_field |
建立矢量场数据 |
Volume_field |
建立提数据 |
Filters
Filters |
说明 |
Contour |
对输入数据集计算等值面 |
Cut_plane |
对数据进行切面计算,可以交互的更改和移动切面 |
delaunay2D |
执行二维delaunay三角化 |
Delaunay3D |
执行三维delaunay三角化 |
Extract_grid |
允许用户选择structured grid的一部分数据 |
Extract_vector_norm |
计算数据矢量的法向量,特别用于计算矢量数据的梯度时 |
Mask_points |
对输入数据进行采样 |
Threshold |
去一定阈值范围内的数据 |
Transform_data |
对输入数据执行线性变换 |
Tube |
将线转成管线 |
Modules
Axes |
绘制坐轴 |
Glyph |
对输入点绘制不同类型的符号,符号的颜色和方向有该点的标量和向量数据决定 |
Glyph |
对输入点绘制不同类型的符号,符号的类型和方向由该点的标量和矢量数据决定 |
iso_surface |
对输入数据绘制等值面 |
Outline |
对输入数据绘制外轮廓 |
Scalar_cut_plane |
对输入的标量数据绘制特定位置的切平面 |
Streamline |
对输入矢量数据绘制流线 |
Surface |
对数据(KTV dataset, mayavi sources)建立外表面 |
Text |
绘制一段文本 |
Vector_cut_plane |
对输入的矢量数据绘制特定位置的切平面 |
Volume |
表示对标量场数据进行体绘制 |
Question: 如果需要对静电场中的等势面进行可视化,需要使用什么控制函数对输入数据进行计算?
Answer: Modules.streamline()
3.4.6. 标量数据可视化
生成标量数据
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) from mayavi import mlab mlab.contour3d(s)
切平面
mlab.pipeline.scalar_field(s) #设定标量数据场
plane_orientation = “x_axes” #设定切平面的方向
index.slice(10) #每10个点用1个点显示
from mayavi import mlab from mayavi.tools import pipeline 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()
对物体设置透明度,再做切割
from mayavi import mlab from mayavi.tools import pipeline 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.show()
Disagreemet:
Question:
1. 1.Mlab中什么控制函数进行切平面绘制?有什么特点?
2. 2.实例中,可视化使用了什么方法绘制特定平面的特平面?
Answers:
1. 1.使用mlab.pipeline.image_plane_widget对切平面绘制,特点是切平面可以任意移动和旋转
2. 2.使用mlab.pipeline.scalar_cut_plane绘制特定平面的切平面
3.4.7. 矢量数据可视化
import numpy as np #构建3维坐标 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) #显示函数 from mayavi import mlab mlab.quiver3d(u,v,w) #框架 mlab.outline() mlab.show()
降采样
由于函数立方体分布过于密集,用Masking Vector采样中的mlab.pipeline.vectors(x,x,x)进行降采样
import numpy as np
from mayavi.filters import mask_points
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)
from mayavi import mlab
# mlab.quiver3d(u,v,w)
# mlab.outline()
# mlab.show()
src = mlab.pipeline.vector_field(u,v,w)
mlab.pipeline.vectors(src, mask_points=10, scale_factor=2.0) #放缩比例为2.0
mlab.show()
采用切面的方式:mlab.pipeline.vector_cut_plane(u,v,w)
级数的等值面
import numpy as np from mayavi.filters import mask_points 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) from mayavi import mlab src = mlab.pipeline.vector_field(u,v,w) # mlab.pipeline.vector_cut_plane(src, mask_points=10, scale_factor=2.0) magnitude = mlab.pipeline.extract_vector_norm(src) mlab.pipeline.iso_surface(magnitude, contours=[2.0,0.5]) mlab.outline() mlab.show()
流线可视化
import numpy as np from mayavi.filters import mask_points 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) from mayavi import mlab # mlab.quiver3d(u,v,w) # mlab.outline() # mlab.show() src = mlab.pipeline.vector_field(u,v,w) # mlab.pipeline.vector_cut_plane(src, mask_points=10, scale_factor=2.0) flow = mlab.flow(u,v,w,seed_scale=1, seed_resolution=5, integration_direction="both") mlab.outline() mlab.show()
矢量场复合观测
import numpy as np from mayavi.filters import mask_points from matplotlib.scale import scale_factory 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) from mayavi import mlab # mlab.quiver3d(u,v,w) # mlab.outline() # mlab.show() src = mlab.pipeline.vector_field(u,v,w) magnitude = mlab.pipeline.extract_vector_norm(src) iso = mlab.pipeline.iso_surface(magnitude,contours=[2.0,],opacity=0.3) vec = mlab.pipeline.vectors(magnitude,mask_points=40, line_width=1, color=(0.8,0.8,0.8), scale_factor=4.) # mlab.pipeline.vector_cut_plane(src, mask_points=10, scale_factor=2.0) 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.outline() mlab.show()
Ques:
1.标量数据和矢量数据分别使用什么方法进行绘制?
2. 2.矢量数据可视化实例中是如何对数据进行降采样的?
Answer:
1. 1. mlab.contour3d(x,y,z) and mlab.quiver3d(x,y,z)进行绘制
2. 2. Masking vector采样中的mlab.pipeline.vectors(src,mask_points=10,scale_factor=2.0)
4. Mayavi三维可视化
4.1. 绘制数据dragon
程序框架:
- 打开文件
- 使用modules绘制数据的surface
- 显示可交互的结果
渲染dragon ply文件: