scientific computation and 3D visualization

19 minute read

Published:

[TOC]

Python科学计算三维可视化【完结】

中国MOOC《Pyhton计算计算三维可视化》总结

课程url:here ,教师:黄天宇,嵩天

下文的图片和问题,答案都是从eclipse和上完课后总结的,转载请声明。

Python数据三维可视化

1Introduction

1.1可视化计算工具

1.1.1TVTK 科学计算三维可视化基础

Mayavi 三维网格面绘制,三维标量场和矢量场绘制

TraitsUI 交互式三维可视化

SciPy 拟合,线性差值,统计,插值

数据过滤器

需要安装的软件:VTK, Mayavi, numpy, PyQt4, Traits, TraitsUI

1.2内容组织

流体数据的标量可视化、矢量可视化实例

三维扫描数据(模型/地形)

三维地球场景可视化实例

曲线UI交互控制可视化

2基础运用

2.1TVTK入门

科学计算可视化主要方法

  • 二维标量数据场:颜色映射法,等值线法,立体图/层次分割法
  • 三维标量数据场:面绘制法,体绘制法
  • 矢量数据场:直接法,流线法

下载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.4TVTK管线与数据加载

  • TVTK管线分两部分:数据预处理和图形可视化
  • 数据预处理以s.output_port和m.input_connection形式输出
  • 管线的两种类型:可视化管线(将原始数据加工成图形数据),图形管线(图形数据加工成图像)
  • 可视化管线分两个对象:PolyData(计算输出一组长方形数据)和PolyDataMapper(通过映射器映射为图形数据)
TVTK对象说明
Actor场景中一个实体,描述实体位置,方向,大小的属性
Renderer渲染作用,包括多个Actor
RenderWindow渲染用的图形窗口,包括一个或多个Render
RenderWindowInteractor交互功能,评议,旋转,放大缩小,不改变Actor或数据属性,只调整场景中照相机位置
  • 管线的数据可以表示如下:

img

  • 总结下TVTK管线就分为以下几个部分:数据预处理,数据映射,图形绘制,图形显示与交互
  • 建立长方形模型:

2.4.1IVTK观察管线

代码例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()

复制代码

显示结果:

img

有会出现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后第窗口界面,注意左侧的菜单栏,有分级

img

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.1Tvtk数据集(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.3Tvtk读取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()

复制代码

img

Stl格式数据,可以在python三维可视化中打开,也就是说solidworks中创建的stl文件也可以在python三维可视化中打开。

2.4.4Tvtk读取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)

复制代码

3VTK可视化基础实战

介绍三类可视化方法:标量可视化,矢量可视化,轮廓化可视化

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()

复制代码

img

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()

复制代码

得到结果:

img

  • vtk.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()

复制代码

显示结果

img

  • 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.2TVTK库实战练习

  • 练习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()

复制代码

img

代码例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()

复制代码

img

  • 练习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.3Mayavi库入门

类别说明
绘图函数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)

img

代码例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()

复制代码

img

Mesh函数是三个二维的参数,点之间的连接关系,尤其由x,y,z之间的位置关系所决定。

上面这个例子如果改变代码行为mlab.mesh(x,y,z,representation=”wireframe”,line_width=1.0)

则结果为

3.3.2Mayavi管线(分析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.4Mayavi库入门

3.4.1基于numpy数组的绘图函数

  • Mlab对numpy建立可视化过程:
  1. 建立数据源
  2. 使用filter(可选)
  3. 添加可视化模块

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)

复制代码

img

参数说明
ColorVTK对象的颜色,定义为(0,1)的三元组
ColormapColormap的类型,例如Reds、Blues、Copper等
Extentx,y,z数组范围[xmin,xmax,ymin,ymax,zmin,zmax]
Figure画图
Line_width线的宽度,该值为float,默认为0.2
Mask_points减小/降低大规模点数据集的数量
Mode符号的模式,例如2darrow、2dcircle、arrow、cone等
NameVTK对象名字
OpcityVTK对象的整体透明度,改值为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()

img

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()

复制代码

img

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)

复制代码

img

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)

img

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)

img

Questions:

  1. points3D和Plot3D两个函数之间的区别于联系是什么?
  2. Imshow()方法是如何确定二维数组可视化图像颜色的?
  3. Surf()方法实例中通过什么方法获取x,y二维数组的?
  4. Mlab中可以进行矢量数据可视化的方法有哪些?

Corresponding answers:

  1. Points3D是基于Numpy数组x,y,z提供的数据点坐标,绘制图形;Plot3D是基于1维numpy数组x,y,z供的三维坐标数据绘制图形;
  2. Imshow()通过colormap关键字确定颜色,比如colormap=’gist_earth’,确定颜色为“类似地球表面颜色”;
  3. Surf()方法是通过np.mgrid(xxx,xxx)获取x,y二维数组;
  4. 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()

复制代码

img

代码例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()

复制代码

img

3.4.3Mlab控制函数

图像控制函数:

函数图像说明
Clf清空当前图像mlab.clf(figure=None)
close关闭图形窗口 mlab.close(scene=None, all=False)
Draw重新绘制当前图像mlab.close(figure=None)
Figure建立一个新的scene或者访问一个存在的scenemlab.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=NoneReset_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()

复制代码

img

简述选取红色小球问题分析实例程序的基本框架和搭建流程

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.5Mlab控制函数(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)

img

切平面

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()

复制代码

img

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()

复制代码

img

降采样

由于函数立方体分布过于密集,用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()

复制代码

img

采用切面的方式:mlab.pipeline.vector_cut_plane(u,v,w)

img

级数的等值面

复制代码

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()

复制代码

img

流线可视化

复制代码

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()

复制代码

img

矢量场复合观测

复制代码

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()

复制代码

img

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)

4Mayavi三维可视化

4.1绘制数据dragon

程序框架:

  • 打开文件
  • 使用modules绘制数据的surface
  • 显示可交互的结果

渲染dragon ply文件:

from mayavi import mlab
import shutill #shutil可以中间删除显现的文件
mlab.pipeline.surface(mlab.pipeline.open(dragon_ply_file))
mlab.show()

代码例19

img View Code

img

4.2绘制数据canyon

代码例20

img View Code

img

4.3绘制数据canyon

二维坐标如何转换成三维坐标?

复制代码

x = R*cos(lat)*cos(lng);
y = R*cos(lat)*sin(lng);
z = R*sin(lat);
如果R = 1, 则
x = cos(lat)*cos(lng);
y = cos(lat)*sin(lng);
z = sin(lat);
lng表示经度,lat表示维度

复制代码

代码例21

img View Code

img

5Mayavi三维可视化

5.1三维可视之基础应用homework1

pass见下文url

5.2三维可视之基础应用homework2

pass见下文url

5.3三维可视之基础应用homework3

pass见下文url

5.4三维可视之基础应用homework4

pass见下文url

5.5三维可视之进阶实战homework5

构造一个旋转抛物面,并使用mlab.mesh绘制出来。首先在(r, theta)中创建一个20*20的二维网格:

r, theta = mgrid[0:1:10j, 0:2*pi:10j]

并将圆柱坐标系,转换为直角坐标系,其中:

z = r*r
x = r*cos(theta)
y = r*sin(theta)

(数学函数等值可从numpy中导出。)

代码例22

复制代码

from mayavi import mlab
import numpy as np

pi = np.pi
cos = np.cos
sin = np.sin
mgrid = np.mgrid

r,theta = pi/250,pi/250
[r,theta] = np.mgrid[0:1:10j,0:2*pi:10j]

x = r * cos(theta)
y = r * sin(theta)
z = r * r

s = mlab.mesh(x,y,z)
mlab.show()

复制代码

img

5.6三维可视之进阶实战homework6

对“编程练习8.1”中旋转抛物面方程进一步绘制,计算一个二维数组 s,并且把它传递给mesh()的scalars 参数。观察一下绘制结果的变化。其中 s = xyz. 同时,请绘制该旋转抛物面的轮廓线。

空间轮廓线可视化代码:

img View Code

5.7三维可视之进阶实战homework7

可视化模型数据文件(附件),能发现了什么?

能发现一只白色雕塑的兔子

对于tar.gz类型压缩包的处理,可以参考dragon模型,可以参考以下代码:

img View Code

大致逻辑如下:

选中并打开bunny.tar.gz—新建文件夹bunny_data—解压bunny.tar.gz到bunny_data文件夹—关闭bunny.tar.gz—串联路径从bun.zipper.ply(一般ply文件是最终目录下的扫描文件)到上一级再到上一级到最终建立的文件夹bunny_data—打开上面构建好的路径下的ply文件,用mlab.pipeline.surface()构建表面—用shutil.rmtree删除用于放置压缩文件的文件夹。

代码:

img View Code

补充:mlab绘图函数的x、y、z、s、w、u、v到底是什么含义?假设这些参数描述了一个磁场,它们可能分别代表什么含义?加入这些参数描述了一个流体,它们可能分别代表什么含义?

X,y,z表示点三维坐标;

S表示该坐标点处的标量值;

U,v,w表示矢量元素

如果应用到磁场中,x,y,z表示磁场位置,s表示该位置处磁场大小,u,v,w表示该处磁场方向。

如果应用到流体,x,y,z表示流体位置,s表示该处流量大小,u,v,w表示该处流量方向。

LOD:level of details

5.8三维可视之进阶实战homework8

1.为mayavi可视化提供数据的mayavi管线层级是Filters,这句话对吗?为什么?

不对,因为为mayavi可视化提供数据的是scence场景,scence每个场景下有多个数据集合sources,为mayavi可视化提供数据,Filter是应用于source上对数据进行变换。

2.基于1维Numpy数组x、y、z提供的三维坐标数据,绘制线图形的函数是Point3D()。这句话正确吗?为什么?

不对,因为基于1维Numpy数组x,y,z提供的三维坐标数据,绘制线图形的函数是plot3D(), point3d()是基于数组x,y,z提供的三维点坐标,绘制点图形。

3.mayavi管线中处于最顶层表示场景的对象是什么?获取当前场景的方法是什么?

Mayavi中处于最顶层的对象是mayavi Engine,表示建立和销毁场景Scene。

获取当前场景的方法是s.scene.background()

4.3D绘图函数Point3D()中,根据标量值确定actor透明度的参数是opcity。这句话正确吗?为什么?

不对,根据标量值确定actor透明度的参数是transparent,opcity用于VTK对象的整体透明度,该值为float型,默认为1.0

5.3D绘图函数中,绘制由三个二维数组x、y、z描述坐标点的网格平面的方法是imshow()。这句话正确吗?为什么?

不对,imshow()是用于绘制二维数组的,但是没有z轴,只有x和y两个轴,x作为第一轴的下标,y轴作为第二轴的下标

比如:s = numpy.random.random((10,10)),img = mlab.imshow(s,colormap=’gist_earth’)

6.3D绘图函数中,三维矢量数据的可视化的方法是contour3d()。这句话正确吗?为什么?

Contour3d是用来绘制标量数据3d视图的,三维矢量数据可视化的方法是mlab.quiver3d()。

7.在鼠标选取操作中,on_mouse_pick()方法返回值是什么?

On_mouse_pick()返回一个vtk对象。

8.mlab管线中,用来进行数据变换的层级是什么?用来实现数据可视化的层级是什么?

用filter对数据进行交换,用modules来对最终的数据进行可视化。

9.mlab管线的modules层级中,用来对VTK dataset和mayavi sources建立外表面的方法是surface()。这句话正确吗?为什么?

正确,但是要却别与iso_surface(),iso_surface()是用于对输入的体数据绘制其等值面。

10.mayavi可视化实例三中,绘制大洲边界时大洲边界粗糙的解决办法是什么?

调整LOD,比如调整continents_src.data_source.on_ratio = 2

6三维可视化之交互界面

6.1三维可视之进阶实战homework8

• Traits背景: Python动编程态语言,变量没有类型,比如:颜色属性 “Red”字符创 0xff0000整数 (255,0,0)元组 • Traits库可以为python添加类型定义 • Traits属于解决color类型的问题 o 接受能表示颜色的各种类型值 o 赋值为非法的颜色值时,能够捕捉到错误,并给提供错误报告。 o 提供一个内部的标注你颜色 • c.color可以支持颜色命令,如c.color = “red”,但不支持c.color = “abc”的字符串 • c.configure_traits()可以设置颜色,c.color.getRgb()可以获取设置颜色后的三原色的值 比如设置c.configure_traits()为红色,即在桌面弹出的窗口中设置Red,那么回击c.color.getRgb可以得到(255,0,0,255)这样的feedback。

6.2attributes of traits

traits的五个功能:initialization, verification, procuration, monitoring, visualization

代码23 traits

复制代码

from traits.api import Delegate, HasTraits, Instance, Int, Str
 
class Parent(HasTraits):
    # 初始化
    last_name = Str('Zhang')
 
class Child(HasTraits):
    age = Int
    # 验证
    father = Instance(Parent)
    # 代理
    last_name = Delegate('father')
    # 监听
    def _age_changed(self, old, new):
        print('Age change from %s to %s' % (old, new))

复制代码

练习过程如下:

img View Code

在traits属性功能的实例中,能否直接修改Child的last_name属性?

不能,因为Child对象的last_name是直接继承自Parent类的,要通过父类改变

如果定义P = Parent(), c = Child();

直接输出c.last_name 没有结果

所以输出c.father = P, 再输入c.last_name就有子类名字

或者也可以直接输入P.last_name也可以得到子类名字

6.3traits属性监听

Trait属性监听:静态监听,动态监听

Trait监听属性顺序:name, age, doing—静态监听函数—动态监听1—动态监听2

静态监听函数的几种形式:属性名+changed+发生变化前的名+发生变化后的名字

_age_changed(self)
_age_changed(self,new)
_age_changed(self, old, new)
_age_changed(self, name, old, new)

动态监听:

@on_trait_change(names)
Def any_method_name(self, ..)

img

问:为什么对Infoupdated任意赋值都会触发监听事件?

因为Infoupdated直接由Event赋值,无论如何都会调用_Infoupdated_fired()函数,所以会触发self.reprint()函数输出self.name和self.age内容。

6.5Traits_property

用traits_property.py遍好程序后,得到area被监听的结果;如果命令行输入w/h发生变化,print输出的就是变化后的值。

调用r.edit_traits()直接触发_get_area()函数,同时在界面中显示area结果。

img

6.6TraitsUI

Tkinter, wxPython, pyQt4, TraitsUI(based on MVC:Model-View-Controller)

MVC是traitsUI所使用的架构模型

6.6.1Traits_UI交互

复制代码

from traits.api import HasTraits, Str, Int
class ModelManager(HasTraits):
    model_name = Str
    category = Str
    model_file = Str
    model_number = Int
model = ModelManager()
model.configure_traits()

复制代码

img

6.6.2View定义界面

TraitsUI自定义界面支持的后台库界面有:qt4(-toolkit qt4)和wx(-toolkit wx)

MVC类别MVC说明
ModelHasTraits的派生类用Trait保存数据,相当于模型
View没有指定界面显示方式时,Traits自动建立默认界面
Controller起到视图和模型之间的组织作用,控制程序的流程

•Item对象属性

Item(id,name,label)

属性说明
idItem的唯一ID
nameTrait属性的名称
Label静态文本,用于显示编辑器的标签
Tooltip编辑器的提示文本

•View对象属性

属性说明
Title窗口标题栏
Width窗口高度
Height串口高度
Resizable串口大小可变,默认为True

代码和界面如下:

img

问:如果想要编辑器窗口大小不能改变,应如何修改view中的哪个属性?

答:修改title中的resizable = False可以是标签大小不可变

6.6.3Group组织对象

Group对象

from traitsui.api import Group

Group(…)属性有:

属性说明
Orientation编辑器的排列方向
Layout布局方式normal,flow,split,tabbed
Show_labels是否显示编辑器的标签
Columns布局的列数,范围为(1,50)

· Group类继承的HSplit类

复制代码

Hsplit定义:
Class HSplit(Group):
    #...
    #...
    Layout = “split”
    Orientation = “horizontal”

复制代码

代码等价于:

Group(…, layout = “split”, orientation = “horizontal”)

•Group的各种派生类

属性说明
HGroup内容水平排列Group(orientation = “horizontal”)
HFlow内容水平排列,超过水平宽度,自动换行,隐藏标签文字。Group(orientation = “horizontal”, layout=”flow”, show_labels = False)
HSplit内容水平分隔,中间插入分隔条
Tabbed内容分标签页显示Group(orientation=”horizontal”,layout=”tabber”)
Vgroup内容垂直排列Group(orientation=”vertical”)
Vflow内容垂直排列,超过垂直高度时,自动换列,隐藏标签文字Group(orientation=”vertical”,layout=”flow”,show_labels=False)
Vfold内容垂直排列,可折叠Group(orientation=”vertical”,layout=”fold”,show_labels=False)
Vgrid按照多列网格进行垂直排列,columns属性决定网格的列数Group(orientation=”vertical”,columns=2)
Vsplit内容垂直排列,中间插入分隔条Gorup(orientation=”vertical”,layout=”split”)

代码24 多视图界面代码

img View Code

img

•垂直排列多视图

img View Code

img

•水平排列多视图

img View Code

img

•Hsplit和VGroup定义水平/垂直并排视图

同样也可以用HSplit和VGroup去生成水平/垂直排列

img View Code

img

  • 外层垂直排列

img View Code

img

  • 内外部视图显示

  • 代码25

img View Code

  • 在命令行输入不同代码出现不同界面:
>>> model.configure_traits(view = global_view)

img

>>> model.configure_traits()

img

>>> model.configure_traits(view = "traits_view")

img

如果想要在编辑器中水平并列显示三组group对象

Q1.如果想要在编辑器中水平并列显示三组group对象,应该如何修改group对象的属性?

A1.把原来的Group()改成HGroup()或者在列完3个内层Group同级上写orientation = “horizontal”

Q2.如果想要在编辑器中垂直分标签页显示若干组group对象,可以使用哪些方法?

同理把原来的Group()改成VGroup()或者在列完若干个内层Group()同级上写orientation = “vertical”

6.6.4视图配置

通过kind属性设置view显示类型

显示类型说明Modal模态窗口,非即时更新Live非模态窗口,即时更新Livemodal模态窗口,即时更新Nonmodal非模态窗口,非即时更新Wizard向导类型Panel嵌入到其他窗口中的面板,即时更新,非模式Subpanel 
  
显示类型(采用窗口显示内容)
Modal
Live
Livemodal
nonmodal

模态窗口:在窗口关闭之前,其他窗口不能激活;

无模态窗口:在窗口关闭之前,其他窗口能激活;

即时更新:修改空间内容,立即反映到模型数据上;

非即时更新:只有当用户点ok,apply等命令时,效果才会反应在模型上;

Wizard:向导窗口,模态窗口,即时更新;

Panel:向导窗口,模态窗口,即时更新

subpanel :嵌入窗口中的面板

视图配置的实例:view = view(… kind = ‘modal=’)

模态与非模态的小例子

Configure_traitsEdit_traits()
界面显示后,进入消息循环界面显示后,不进入消息循环
主界面窗口或模态对话框无模态窗口或对话框

Traits UI按钮配置

标准命令按钮
UndoButton
Applybutton
ReverButton
OKbutton
CancelButton
HelpButton
Traitsui.menu预定义了命令按钮:
OKcancelButtons = [OKButton,CancelButton]
ModelButtons = [ApplyButton,RevertButton,OKButton,CancelButton,HelpButton]
LiveButtons = [UndoButton,ReverButton,OKButton,Cancel]

6.6.5TraitsUI控件

文本编译器:Str, Int

文本编译器与密码窗口:

img View Code

img

代码26 滑动条

img View Code

img

text = TextEditor()
text.configure_traits()

img

按钮Button Editor
监听方法: _TraitName_fired()
TraitName是Button Trait 的名字,即my_button
Def _my_button_fired(self):
    Self.counter += 1

程序框架:

复制代码

from traits.api import Button #导入控件模块
class ButtonEditor(HasTraits):
    TraitName = Button() #定义按钮变量名
    def _TraitName_fired(self) #定义监听函数
       … …
    view = View()
button = Button()
button.configure_traits()

复制代码

菜单、工具栏

From traitsui.menu import Action…
对象说明
Action在Menu对象中,通过Action对象定义菜单中的每个选项
ActionGroup在菜单中的选项中进行分组
Menu定义菜单栏中的一个菜单
MenuBar菜单栏对象,由多个Menu对象组成
ToolBar工具栏对象,它由多个Action对象组成,每个Aciton对应工具挑中的一个按钮

fdf控件列表

对象说明
Array数组空间
Bool单选框、复选框
Button按钮
Code代码编辑器
Color颜色对话框
Directory目录控件
Enum枚举控件
File文件控件
Font字体选择控件
HtmlHtml网页控件
List列表框
Str文本框
Password密码控件
Tuple元组控件

7三维可视化之界面实战

7.1TraitsUI与mayavi实战

7.1.1Mayavi可视化实例

建立mayavi窗口步骤:   1. 建立从HasTraits继承的类     a. 建立MlabSceneMode场景实例scene     b. 建立view视图     c. 定义_init_函数,生成数据   2. 建立类的实例,调用configure_traits()方法

Numpy   用于建立数据

Traits.api,traitsui.api    用于建立场景模型

Tvtk.pyface.scene_editor    用于建立视图

Tools.mlab_scene_model    用于绘制数据

Core.ui.mayavi_scene    用于绘制数据

imgimg

7.1.2TraitsUI可视化实例

程序框架

#1.定义HasTraits继承类

复制代码

Class MyModel(HasTraits):
#1.1定义窗口的变量
n_meridional
n_longitudinal
scene
#1.2更新视图绘制
@on_trait_change()
Def update_plot(self):
    … …
#1.3建立视图布局
View = View()

复制代码

#2.显示窗口

model = MyModel()
Model.configure_traits()

img

img

7.1.3三维可视之交互界面homework6

pass见下文url

8三维可视化之总结

8.1客观题练习homework7

pass见下文url

8.2主观题练习

8.2.1练习1

请参考SV11V02“TraitsUI可视化实例”,将本课程所学的TVTK或者Mayavi可视化例子,补充TraitsUI的交互控制,即通过TraitsUI的交互控制能够实现可视化视图中参数的相应改变,交互控件的种类不少于2种(如滑动条、文本框)、交互控件数量不少于3个(如2个滑动条、1个文本框)。要求代码规范,有注释。

SV11V02 TraitsUI可视化实例参考代码

一个简单的例子,在原有基础上,融合了文本框和[‘OK’]按钮

img View Code

代码27 view_range_text

img View Code

img

参考SV09V02“TraitsUI可视化实例”,将本课程所学的TVTK或者Mayavi可视化例子,补充TraitsUI的交互控制,即通过TraitsUI的交互控制能够实现可视化视图中参数的相应改变,交互控件的种类不少于3种(如滑动条、文本框、颜色对话框)、交互控件数量不少于3个(如1个滑动条、1个文本框、1个颜色对话框)。要求代码规范,有注释。

8.2.2练习2

SV09V02“TraitsUI可视化实例”参考代码:

复制代码

from traits.api import Delegate, HasTraits, Instance, Int, Str

class Parent(HasTraits):
    # 初始化
    last_name = Str('Zhang')
 
class Child(HasTraits):
    age = Int
    # 验证
    father = Instance(Parent)
    # 代理
    last_name = Delegate('father')
    # 监听
    def _age_changed(self, old, new):
        print('Age change from %s to %s' % (old, new))

复制代码

代码28 在TraitsUI中嵌入mayavi

颜色对话框没有找到,不会实现这个功能,不过添加了一个点击绘图的命令,代码稍微修改了下,添加了_plotbutton_fired(self)和plot(self)函数,同时在绘图之前要给图形一个初始化,在出现图形界面后,再动态监听图形参数的变化

img View Code

img

本博客中能提供到的

1.pdfhomework文本和答案;

2.部分数据集代码,如果选哟全部数据集,最好还是取中国MOOC顶部的url课程链接中下载,资料全;

3.关于这个课程,我做过编程训练的代码

4.pdf课程笔记。

github地址:here,上面对应的资料都在里面,不专业,不过代码都走了一遍,有些问题也想了下,供参考。

关于如何git上传,转一下这个大佬帖子,here

简单老说就是以下几个步骤:

1).在github中创建好新的repository,如下图,其次就是命名,其他默认即可。

img

img

2).把要上传的文件装在一个文件夹下;

img

3).右击这个文件夹,会出现git Bash和git GUI这个命令,点击git Bash(前提是已经装好了git);

img

4).进入git Bash后,是这个界面

img

5).刚才创建好的repository里,复制链接

img

6).截下来在git Bash中输入下面命令

a)git clone xxxx(刚才复制的地址),此时在本地要上传的文件夹里会多出一个文件夹(同文件名github中,创建的repository),比如我是Visualization;

  e.g. git clone https://github.com/nityuyukun/Visualization.git

img

b).切换到本地仓库的文件夹,比如Visualiazation

img

c)git add . //注意add后有一个空格,再加点,加点表示上传所有文件到本地仓库;

d)git commit -m “xxx” //”xxx”中的xxx可以任意替换,表示想要备注的名字,比如我下面是second commit,这一步表示确认上传所有文件到本地仓库,并备份;

这两步完后,出现下图

img

e)git push -u origin master 这一步表示把本地仓库里的东西推到github上。

img

finished.