Python三维数据可视化

这是上完中国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建立可视化过程:
  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)

参数

说明

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:

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

代码例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文件:

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

猜你喜欢

转载自www.cnblogs.com/yuyukun/p/12063595.html
今日推荐