2014-03-07 34 views
1

我正在努力使用从文件读入的数据在mayavi中做一个简单的contour3d图。该数据的格式为使用(mayavi)mlab.contour3d绘制存储在文件中的数据?

x1 y1 z1 val(x1,y1,z1) 
    x1 y1 z2 val(x1,y1,z2) 
    . .  .  . 
    x1 y1  z_K val(x1,y1,z_K) 

    x1 y2  z1 val(x1,y2,z1) 
    . .  .  . 
    . .  .  . 
    x_L y_M z_K val(x_L,y_M,z_K) 

(这里在每一行的第一个3个值给(X,Y,Z)的点的坐标的规则三维笛卡尔网格而第四值给出一个标量的值在这一点上,我可以粘贴)

数据文件可以使用numpy.loadtxt成功读取一个小例子文件,如果是有用的,但我怎么从那里 得到使用(Mayavi的)MLAB绘制等值面。 contour3d?我认为loadtxt的默认输出 数组对于mlab.contour3d格式不正确。

我已经能够找到mlab.contour3d的所有例子都使用ogrid生成一个网格,然后绘制这个网格的一个简单函数(sin等)。我已经能够成功地运行这些示例,但他们并没有告诉我如何从文件中读取数据,并将其准备好用于绘图的正确格式 。如果有人能给我一个指针,我肯定它会帮助很多新手处于类似的位置;绘制由另一个程序生成的文件中存储的三维数据肯定是科学家必须做的最常见的绘图任务之一。

+0

这将有助于如果你可以添加一些示例数据(从您的数据文件,例如几行)和你的代码读取文件。然后,人们可以向您展示如何从该解决方案转变为可行的解决方案。 – YXD

回答

0

向E先生道歉,因为延迟回复,周末我没有上网。 但是,我确实可以使用计算机,并且我已经找到了我的问题的答案,尽管这是一个稍微难看的问题。我相信可以改进以下方法,并且出于上述原因,我知道这是3D绘图软件的重要基本用法,所以如果任何人有任何改进,他们可以提供他们将不胜感激。下面的解释假定您使用的是Linux,但我确定在其他操作系统上执行相同的操作(即保存并运行python文件)非常简单。

先到生成样本数据文件。真正的数据来自Fortran程序,但为了当前的测试目的,我将使用python生成示例数据文件。将以下代码存储在文件“gen-data.py”中(复制到您最喜爱的文本编辑器中并粘贴到然后点击“保存为”等)

#!/usr/bin/python 
import numpy as numpy 

# run this program with 
#" python gen-data.py > stream.out " 
# to generate sample data file stream.out 
x_low = -1 ; x_upp = 1 ; NX = 5 
y_low = -2 ; y_upp = 2 ; NY = 3 
z_low = -3 ; z_upp = 3 ; NZ = 3 

x_arr = numpy.linspace(x_low,x_upp,num = NX, endpoint=True) 
y_arr = numpy.linspace(y_low,y_upp,num = NY, endpoint=True) 
z_arr = numpy.linspace(z_low,z_upp,num = NZ, endpoint=True) 

#the following line generates data (for distance from the origin) 
# over a structured grid 
for x in x_arr: 
    for y in y_arr: 
     for z in z_arr: 
      print x , y , z , x**2 + y**2 + z**2 

运行使用 蟒程序gen-data.py> stream.out ,其将存储在上述数据文件中描述的类型的一个示例数据文件“流.OUT”。你应该与值的文件:
-1.0 -2.0 -3.0 14.0
-1.0 -2.0 0.0 5.0
-1.0 -2.0 3.0 14.0
-1.0 0.0 -3.0 10.0
-1.0 0.0 0.0 1.0
-1.0 0.0 3.0 10.0
-1.0 2.0 -3.0 14.0
-1.0 2.0 0.0 5.0
-1.0 2.0 3.0 14.0
-0.5 -2.0 -3.0 13.25
。 。 。 。
0.5 2.0 3.0 13.25
1.0 -2.0 -3.0 14.0
1.0 -2.0 0.0 5.0
1.0 -2.0 3.0 14.0
1.0 0.0 -3.0 10.0
1.0 0.0 0.0 1.0
1.0 0.0 3.0 10。0
1.0 2.0 -3.0 14.0
1.0 2.0 0.0 5.0
1.0 2.0 3.0 14.0
在数据文件中的每个行是形式
XYZⅤ的(X,Y,Z)
其中x,y, z描述空间中点的x,y,x坐标,V(x,y,z)表示标量在该点的值。

绘制数据
我们的问题是如何使用Mayavi的绘制该数据 - 我在绘制等值面,这可以使用contour3d命令来实现特别感兴趣 。 网络上的众多示例显示contour3d使用mgrid命令生成 的数据。 (也有使用ogrid命令的例子,但对我来说, 更容易理解)。 策略:如果我们可以操纵我们的数据具有相同的形状,并且从mgrid命令的输出中,我们应该可以绘制它。 分析来自mgrid的输出,很明显所需要的是用于存储x,y和z坐标的numpy数组,以及用于存储标量值(上面的V)的另一个三维numpy数组{ }在这些点上。以下程序 实现了这些步骤。我认为,该方案肯定可以加以改进: 常规fill_up_array可能,我肯定,被一个班轮人谁 知道在Python阵列切片取代,并有可能比其他地方可以 得到改善。我不禁想起整个事情也许可以在1条或2号线的人谁知道他们在做在numpy的/ Mayavi的是什么,但下面 程序来完成,我相信,易于理解和它的作品(你应该看到在出现的情节中的截面球形 表面)。
保存下列文件中的“hope.py”,并与
蟒蛇hope.py运行

import numpy 
from mayavi import mlab 

def fill_up_array(output_arr,source_arr,nx,ny,nz,posn): 
# takes a slice of results from source_arr and writes to output_arr 
# there is probably an easy one liner to do this ? 
#TODO: add checks to ensure input is sensible 
    for i in range(nx): 
     for j in range(ny): 
      for k in range(nz): 
       output_arr[i][j][k] = source_arr[i][j][k][posn] 

# these numbers have to correspond to those used in gen-data.py 
NX = 5 ; NY = 3 ; NZ = 3 

NDIM = 4 # number of columns in data file, 4 for current example 


#initialise arrays: 
# xx will contain x coordinate of data point 
# yy will contain y coordinate of data point 
# zz will contain z coordinate of data point 
# VV will contain sample scalar value at (x,y,z) 
xx = numpy.zeros((NX,NY,NZ)) 
yy = numpy.zeros((NX,NY,NZ)) 
zz = numpy.zeros((NX,NY,NZ)) 
VV = numpy.zeros((NX,NY,NZ)) 


#now read in values from stream.out file to these arrays 
full = numpy.loadtxt("stream.out") 
fy = numpy.reshape(full, (NX,NY,NZ,NDIM)) 


fill_up_array(xx,fy,NX,NY,NZ,0) 
fill_up_array(yy,fy,NX,NY,NZ,1) 
fill_up_array(zz,fy,NX,NY,NZ,2) 
fill_up_array(VV,fy,NX,NY,NZ,3) 


#test plot 
mlab.contour3d(xx, yy, zz, VV) 
mlab.show()