秉着边学边写边折腾的原则,开始粗糙的工作。真正掌握还是得讲解给别人听。 先给出网课
https://www.icourse163.org/course/BIT-1001871001
Mayavi官方
http://docs.enthought.com/mayavi/mayavi/genindex.html
(有时候这网站会装死,一般过几个小时就会活过来)
我发现了,光是三流操作还不够,还得加上四流翻译。
2.0.简述(1):
2.1
.mlab
图形可视化,图像操作2.1.0 绘图函数
2.1.0.0 绘图函数,通用参数
2.1.0.1 .barchart
2.1.0.2 .mesh,.triangular_mesh
2.1.0.3 .imshow,.plot3d
2.1.0.4 .surf,.contour_surf,.contour3d:*当前位置
2.1.0.5.points3d,.quiver3d
2.1.0.6.flow,.volume_slice
2.1.0.7 补充、对比及总结
2.1.0.8 绘图常用的技巧2.1.1 图像控制
2.1.1.0
2.1.2 图像修饰
2.1.3 相机控制
2.1.4 其他2.2
.api
操作管线对象,窗口对象2.2.1 脚本录制
这一章主要讲surf
、contour_surf
、contour3d
绘制
先说surf
,因为经常要用,而且前面提到过,说起来方便。然后contour_surf
,最后是contour3d
1.surf和contour_surf
官方实例,官方也是很友善,把代码合并在一起了。
import numpy as np
from mayavi.mlab import *
def f(x, y):
sin, cos = np.sin, np.cos
return sin(x + y) + sin(2 * x - y) + cos(3 * x + 4 * y)
x, y = np.mgrid[-7.:7.05:0.1, -5.:5.05:0.05]
surf(x, y, f)
contour_surf(x, y, f)
show()
以下是效果图
官方还是很良心的制作了一个,第一个图是surf
第二个是contour_surf
最后那个是两个合并的可视化,这么做不好,因为是我干的,为了省事。
其实我只是想说,两者可以叠加,管线会出现两个层级,还可以继续叠加outline
前面说了
mesh
和surf
的区别,在于绘制的网格的不同,这里再说一次,mesh
的绘制方式是三角形网格,surf
是规整的网格
surf
实际是正交,我在这里增设了一个面,这个面是整个绘制范围,并设置了opacity
,是不是秒懂。(我这里的面设置的高度是1,角度看起来就有点奇怪,设0会好点)
对于
surf
和contour_surf
的简单介绍如下:
surf
:Plots a surface using regularly-spaced elevation data supplied as a 2D array.
contour_surf
:Plots a the contours of a surface using grid-spaced data for elevation supplied as a 2D array.利用形如2D
array
的高程数据绘制具有规整网格的平面
语法如下(两者语法相同)
surf(s, ...)
surf(x, y, s, ...)
surf(x, y, f, ...)
详细说明(也是相同的,措辞微微调整了一下,这里给出
surf(s, ...)
的全文翻译(误))
s
is the elevation matrix, a 2Darray
, where indices along the first array axis represent x locations, and indices along the second array axis represent y locations.
.
x and y can be 1D or 2D arrays such as returned bynumpy.ogrid
ornumpy.mgrid
. Arrays returned bynumpy.meshgrid
require a transpose first to obtain correct indexing order. The points should be located on an orthogonal grid (possibly non-uniform). In other words, all the points sharing a same index in the s array need to have the same x or y value. For arbitrary-shaped position arrays (non-orthogonal grids), see themesh
function.
.
If only 1 array s is passed, the x and y arrays are assumed to be made from the indices of arrays, and an uniformly-spaced data set is created.
If 3 positional arguments are passed the last one must be an array s, or a callable, f, that returns an array. x and y give the coordinates of positions corresponding to the s values.
s
是一个高程矩阵,2维array
的形式,其中第一个位置代表x轴,第二个位置是y轴。
.
x
,y
可以是由numpy.ogrid
或者numpy.mgrid
初始的1维或者2维array
.为了得到正确的索引顺序,被numpy.meshgrid
返回的array
的第一个array
会发生转置.这些点会被放置在正交网格上(可能不均匀).s
中的每一个值所匹配x
,y
的坐标应该具备相同的索引.对于不规则的array
而言(非正交网格),可以参考mesh
.
.
可以只传递1个参数s
,x
,y
的索引已经预设好,这时就创建了一个等间距的数据集。
也可以传递3个参数,最后一个参数必须是一个array
,或者是一个可返回的f
表达式,且返回的类型也是array
,s
值的坐标由前两个参数x
,y
给出。
.
contour_surf
s is the elevation matrix, a 2D array. The contour lines plotted are lines of equal s value.
.
x and y can be 1D or 2D arrays (such as returned by numpy.ogrid or numpy.mgrid), but the points should be located on an orthogonal grid (possibly non-uniform). In other words, all the points sharing a same index in the s array need to have the same x or y value. For arbitrary-shaped position arrays (non-orthogonal grids), see the mesh function.
.
If only 1 array s is passed, the x and y arrays are assumed to be made from the indices of arrays, and an uniformly-spaced data set is created.
.
If 3 positional arguments are passed the last one must be an array s, or a callable, f, that returns an array. x and y give the coordinates of positions corresponding to the s values.官方实例用的就是三个参数的形式.先离散再用绘制,
surf
和contour_surf
传参方式相同。
x, y = np.mgrid[-7.:7.05:0.1, -5.:5.05:0.05]
surf(x, y, f)
然后呢,我想提一下管线
surf
和contour_surf
的配置很相似,上面是surf
下面是contour_surf
surf
多了一层PolyDataNormals
,这里先把问题抛出来,然后讲一点管线。
为什么在这里要讲一下管线配置,因为官方用的就是
surf
做的例子,满满的幸福感,全程翻译。The plotting functions reviewed above explore only a small fraction of the visualization possibilities of Mayavi. The full power of Mayavi can only be unleashed through the control of the
pipeline
itself. As described in the An overview of Mayavi section, a visualization in Mayavi is created by loading the data in Mayavi with data source object, optionally transforming the data throughFilters
, and visualizing it withModules
. Themlab
functions build complex pipelines for you in one function, making the right choice ofsources
,filters
, andmodules
, but they cannot explore all the possible combinations.前面涉及到的绘图函数只探索了Mayavi可视化的一小部分.只有通过管线配置才能充分发挥Mayavi的全部效果。在 An overview of Mayavi章节的叙述中,Mayavi 可以通过配置数据源来创建可视化实例,在这个过程中,可以使用
Filters
任意变换数据,并通过Modules
进行可视化。mlab
函数可以用一条命令生成复杂的管线,并配置正确的数据源sources
,filters
, 和modules
,但是他们无法同时探索所有的可能正确的组合形式。
.
Mlab
provides a sub-module pipeline which contains functions to populate the pipeline easily from scripts. This module is accessible inmlab
:mlab.pipeline
, or can be import frommayavi.tools.pipeline
.
Mlab
提供一个子模块管线,它包含很多用于配置管线的函数,通过脚本可以轻易实现。这个模块可以在mlab
中引用,通过mlab.pipeline
或者mayavi.tools.pipeline
.
When using amlab
plotting function, apipeline
is created: first asource
is created fromnumpy arrays
, thenmodules
, and possiblyfilters
, are added. The resultingpipeline
can be seen for instance with themlab.show_pipeline
command. This information can be used to create the very same pipeline directly using thepipeline
scripting module, as the names of the functions required to create each step of the pipeline are directly linked to the default names of theobjects
created bymlab
on thepipeline
. As an example, let us create a visualization usingsurf()
:
当调用mlab
函数的时候,一条pipeline
管线已经创建好了:首先是由numpy arrays
初始的source
,然后是modules
,可能中间还会有filters
。最后生成的pipeline
管线可以被mlab.show_pipeline
命令显示出来。通过pipeline
管线的脚本模块,这些信息可以用来创建相同的管线,根据名称,可以直接通过object
对象的默认名,直接创建管线的每一步配置。作为例子,我们可以用surf()
做可视化:.
import numpy as np
a = np.random.random((4, 4))
from mayavi import mlab
mlab.surf(a)
mlab.show_pipeline()
The same
pipeline
can be created using the following code:
相同的管线,也可以用以下代码进行创建
import numpy as np
a = np.random.random((4, 4))
from mayavi import mlab
src = mlab.pipeline.array2d_source(a)
warp = mlab.pipeline.warp_scalar(src)
normals = mlab.pipeline.poly_data_normals(warp)
surf = mlab.pipeline.surface(normals)
The following pipeline is created:
Array2DSource
——WarpScalar
————PolyDataNormals
——————Colors and legends
————————Surface
这里不敢展开太细,简单说一下
由numpy
创建的4X4,2Darray
经过Array2DSource
构建了数据源Sources
,到达Filters
层级WarpScalar
,Filters
用于数据变换,PolyDataNormals
也是Filters
的一种,也试数据变换,用于计算法线数据。到最后Modules
可视化层级,Colors and legends
LUT配色方案,Surface
用于绘制平面这个并没有展开说各个层级的具体内容,怎样构建,后面来填坑。
多提醒一句,就是同属于
Filter
层级的WarpScalar
和PolyDataNormals
仍然可以连续建立,还可以多次变换。
.
然后再回到管线讲解之前的内容。
surf
比contour_surf
多了一层Filters
,多做了一次PolyDataNormals
数据变换。
这里还得留一个坑,我并没有发现这一层的具体细节,我删除掉contour_surf
,在PolyDataNormals
之前创建Surface
也能达到同样的效果,这是显然的。隐藏掉
PolyDataNormals
层下的Surface
,直接可视化WarpScalar
的Surface
,也就是少一层PolyDataNormals
数据变换,图像进行对比,还是有细微差别的。
左图是经过PolyDataNormals
数据变换之后的图像细腻一些。
再仔细一点可以想到,左图出现马赛克的地方全是网格绘制走过的地方,这些点的标量值是离散的!是可以确定的值,而这些光滑的地方的数据都是不存在的!可能做了插值,看下图。
我对比过两个
Surface
里面的设置只有Actor
中有设置,而且还全是一样的,Colors and legends
的设置也是一毛一样的。经过一层一层向上对比,找到了PolyDataNormals
里面。最后在
Compute point normals
上发现了,去掉之后就变成了马赛克。。上面两个选项,Auto orient normals
和Compute cell normals
对马赛克都有一定的削弱作用,可能采用不同的算法。
Mayavi文档中也没有对它过多说明,一笔带过,可能要去VTK看看。Computes normals from input data. This gives meshes a smoother appearance. This should work for any input dataset.
简单来说就是用一层
Filter
把网格处理得平滑一点。根本问题还是,我不知道
PolyDataNormals
到底干了什么。
到此为止surf
和contour_surf
是基本说完了。
不知道有没有这样的感觉,surf
和contour_surf
的配置是很简单的,所有的中间管线都被mlab
做好了。
我们至少三种绘图写法:
第一种是直接用
mlab
绘图函数进行,这样做的好处是中间的管线不需要一步一步进行配置,而是直接由mlab
选择默认配置一步到位,很是节约代码。需要一些特殊效果的时候,再手动去设置它的pipeline
管线。但这样做是缺陷的,有一些设置并不能完成,比如刚才出现了一个PolyDataNormals
,它的设置并没有在图形界面中,只能从代码对层面进行配置。另外如果规模大了,手动是一件很费力的事情。
.
所以就有了第二种,用mlab
直接建立完整的管线,用代码微整它的pipeline
管线配置,但是同样有缺陷,有一些更底层的细节无法实现。
.
进而就有了第三种,从pipeline
管线一层一层配置,能发挥它的全部威力,好处不用说了,不好处就是比较麻烦。
.
最后就是,要回到VTK了,更麻烦,但也更强大。毕竟是Mayavi它老爹。
2.contour3d
官方实例,老规矩,+np+show…
import numpy as np
from mayavi.mlab import *
x, y, z = np.ogrid[-5:5:64j, -5:5:64j, -5:5:64j]
scalars = x * x * 0.5 + y * y + z * z * 2.0
contour3d(scalars, contours=4, transparent=True)
show()
然后是这个东西
这次的代码已经有一些变化了,用到了
ogrid
,正愁没地方说ogrid
。刚好,一锅端了,上次说过了mgrid
,入口2.1.2。这次说一下
ogrid
在文末。中间的这个小细节说完了,然后又回到
contour3d
本身是干嘛的讨论来。
估计也看出来了,绘制的是等值面。分别设置contours
为4、6、8、10、40、100之后的图。.官方文档的解释
Plots iso-surfaces for a 3D volume of data suplied as arguments.
为三维数据绘制等值面。语法
contour3d(scalars, ...)
contour3d(x, y, z, scalars, ...)
详细解释
scalars is a 3D numpy arrays giving the data on a grid.
.
If 4arrays
, (x, y, z, scalars) are passed, the 3 firstarrays
give the position, and the last thescalar
value. The x, y and z arrays are then supposed to have been generated bynumpy.mgrid
, in other words, they are 3Darrays
, with positions lying on a 3D orthogonal and regularly spaced grid with nearest neighbor in space matching nearest neighbor in the array. The function builds a scalar field assuming the points are regularly spaced.
.
空间网格的数据scalars
可由numpy
初始化的三维array
给定。
.
如果传递的参数是4个array
(包括x,y,z,scalars),前三个array
给定空间位置,最有一个指定scalars
标量值,x,y,z的array
应由numpy.mgrid
初始化,换言之,他们应当是一个3D的array
,并且规整而且正交的空间网格上就近匹配。给定的空间点是规整的前提之下,这个函数可以建立一个标量场。通过设置
representation=points
到这里可以很清晰地看到空间点了。
以下是我的理解(可能有误)
可能你也看出来了,
surf
、contour_surf
与contour3d
是完全不同的,surf
、contour_surf
的数据主要还是面,设置方式还是在xoy平面上确定坐标值并展示另一个数据,也就是离散了两个值,分别对x、y坐标取了步长,而contour3d
就不同了,它的数据,要取三个步长,离散了xyz三个坐标值,最后是有另外一个用来显示颜色的是标量值。
.
而如果要将空间点连接起来,并不是一件容易的事情,连接方式并不是任意的,而是一需要指定一些方式。和以往的面绘制不太一样,面绘制的时候,空间上的点连接有些是隐性有些是显性,但是说到底,他们还是连接了,区别于根据绘制的不同来确定是否指定绘制方式。但是空间中的点,连接是否有必要,这个我也一直在想。首先要回答的是为什么要连接?其次才能回答,怎样连接。像这个图,绘制的图像是是等值面,那么连接方式是可以确定的。如果你要规定不同的连接方式也是可以的,那么就需要构建新的算法,这是我个人想法。
.
就目前来看,对于空间中的一个点的描述,除了3个坐标位置,这个位置的标量值之外,还有这个位置的矢量信息,从而有需要新的函数和数据进行矢量可视化。后面会专门来说
从管线再说一下。
这个管线和上面还是不太一样的.对于上面的
surf
、contour_surf
它们的层级末端Module
对应的是Surface
而contour3d
的层级末端对应的是IsoSurface
。
IsoSurface
这里有一个例子A module that allows the user to make contours of input volumetric data.
该模块使用户可以使用空间数据绘制等值面。到这里为止,对比两个
Module
的具体设置也不尽相同。
对于IsoSurface
针对的对象是三维数据,是体绘制对象
而对于Surface
的对象是面绘制
3.surf、contour_surf、contour3d的参数
这三个绘制函数的9个共同参数不在这里说了。
需要说明一下的是,
surf
其实是有contours
但是这样做不如直接用contour_surf
,如果仔细看了上面的说明,就会知道surf
多了一个Filter
层级计算,如果只绘制contours
,这个层级就是多余的。因此可以忽略掉surf
的contours
。
在上面的例子中已经给出了contour3d
和contour_surf
的例子,这里进行翻译,给出说明。
contours
Integer/list
specifying number/list ofcontours
. Specifying a list of values will only give the requested contours asked for.
接受的变量类型为int
或者list
.如果指定的参数值是list
,则会按照list
所要求的值进行绘制。上面已经说过了
contours
的例子,用的是int
,按照条数等距绘制,这里给出接受的值是list
的例子,按照值分别绘制。
管线内部的变化
这里设置的contours=[-0.2,0,0.5]
,这就不是等距的等值线设置。
然后继续放大等值线,看看图
上面的图是contour3d
,下面的图是contour_surf
.
mask
boolean mask array to suppress some data points. Note: this works based on colormapping of scalars and will not work if you specify a solid color using the color keyword.
这个至今是个历史悬疑。
representation
the
representation
type used for the surface. Must be ‘surface’ or ‘wireframe’ or ‘points’. Default: surface
representation
类型用于绘制平面的类型。接受的参数为‘surface’
or‘wireframe’
or‘points’
,且默认值为surface
。这个不过多说明了,效果如下,从左到右
points
,wireframe
,surface
warp_scale
scale of the z axis (warped from the value of the scalar). By default this scale is a float value. If you specify
‘auto’
, the scale is calculated to give a pleasant aspect ratio to the plot, whatever the bounds of the data. If you specify a value forwarp_scale
in addition to an extent, the warp scale will be determined bythe warp_scale
, and the plot be positioned along the z axis with the zero of the data centered on the center of the extent. If you are using explicit extents, this is the best way to control the vertical scale of your plots. If you want to control the extent (or range) of the surface object, rather than its scale, see theextent
keyword argument.
z轴的放缩系数。默认情况下scale
是一个浮点数,如果指定为‘auto’
,会得到一个自动适应图像的放缩率,它会根据边界范围给定一个合适的观测比例。如果为warp_scalar
指定一个值,那么图像将会按照指定的值进行放缩,图像将沿着z轴定位,并且将数据的零点放置在中心。如果数据由明确的范围设定,这将是最好的方式来控制图像的纵向比例尺。如果你想控制的是数据的范围(Surface object),而不是它的比例尺,参考extent
参数。就目前为止这个参数还是第一次遇到,以前都没有提到过,所以这里说一下。
这个参数是contour3d
不具备的,下面这个就是直接调整了标量值。
追加三行代码辅助来观察outline
方便观察值域,xlabel
观察量的变化
contour_surf(x, y,f,contours=15,warp_scale=0.1)
outline(color=(1,0,0),opacity=0.8,line_width=1.5)
xlabel('x')
一句话,
warp_scale
就是纵向压缩率。
说得虽然简单,但是细节还是麻烦看一下上方的文档。里面也是有细节的。
4.结尾
补充:
关于
mgrid
和ogrid
,戳这里文章给得挺详细的。
需要说的是,s[0],s[1],s[2]都是可进行运算的,例子中给得是自乘,其实s[0]也是可加减s[1]的
当进行加减运算的时候,会被铺设成空间矩阵。
当各边长都分成3份,想象一个边长为3的矩阵,3X3X3
x,y,z = np.ogrid[-5:5:3j,-5:5:3j,-5:5:3j]
x,y,z本身的维度是对不上的,但一旦相加,各项维度就出来了。
问题汇总:
1.各个层级的具体内容,怎样构建
这个内容很多,打算留链接,单独开一章。
2.
PolyDataNormals
这个怎么做到的,相关的资料。
更新时间
2018.10-10.——
surf
、contour_surf
更完,contour3d
开更,参数未更。
2018.10.11.——目录扩充、contour3d
实例及配图
2018.10.12.——参数补充(更完)