Приношу свои извинения г-ну Э за задержку с ответом, у меня не было доступа в Интернет на выходных. Однако у меня был доступ к компьютеру, и я нашел ответ на свой вопрос, хотя и немного некрасивый. Я уверен, что следующий метод можно улучшить, и по причинам, указанным выше, я знаю, что это важное базовое использование программного обеспечения для 3D-построения, поэтому, если у кого-то есть какие-либо улучшения, которые они могут предложить, они будут очень признательны. В следующем объяснении предполагается, что вы используете Linux, но я уверен, что сделать то же самое (т.е. сохранить и запустить файлы Python) в других операционных системах несложно.
Сначала сгенерируйте образец файла данных. Настоящие данные поступают из программы на Фортране, но для текущих тестовых целей я буду использовать 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
Запустите программу, используя python gen-data.py> stream.out, который будет хранить образец файла данных описанного выше типа в файле данных stream.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 V (x, y, z)
где x, y, z описывают координаты x, y, x точки в пространстве, а V (x, y, z) обозначает значение скаляра в этой точке.
Построение данных
Наша проблема состоит в том, как построить эти данные с помощью Mayavi - меня особенно интересует построение изоповерхностей, которое может быть достигнуто с помощью команды contour3d. Многочисленные примеры в Интернете показывают данные построения contour3d, которые генерируются с помощью команды mgrid. (Есть также примеры с использованием команды ogrid, но для меня mgrid было легче понять). Стратегия: если мы сможем манипулировать нашими данными, чтобы они имели ту же форму, что и вывод команды mgrid, мы должны иметь возможность построить график. Анализируя вывод mgrid, было ясно, что требовалось 3 трехмерные массивы numpy для хранения координат x, y и z и еще один трехмерный массив numpy для хранения скалярных значений (V в приведенном выше) в этих точках. Следующая программа выполняет эти шаги. Я думаю, что программу определенно можно улучшить: я уверен, что подпрограмму fill_up_array можно было бы заменить однострочником кем-то, кто знает о нарезке массивов в python, и, вероятно, есть другие места, которые можно улучшить. Я не могу избавиться от мысли, что все это, вероятно, можно сделать в 1 или 2 строчки для тех, кто знает, что они делают в numpy / mayavi, но следующая программа, я считаю, проста для понимания и работает (вы должны увидеть усеченные сферические поверхности на появившемся графике).
Сохраните следующий файл в "hope.py" и запустите с
python 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()
person
user3390991
schedule
10.03.2014