2012-02-23 7 views
8

ja jak zrobić 3D wykres konturowy pomocą Mayavi w dokładnie taki sam sposób, jak w trzecim rysunku na tej stronie (wodoru elektronów modelu chmury):3D konturu wykres z danych z wykorzystaniem Mayavi/Pyton

http://www.sethanil.com/python-for-reseach/5

Mam zestaw punktów danych, które stworzyłem przy użyciu mojego własnego modelu, z którego chciałbym skorzystać. Punkty danych są przechowywane w wielowymiarowej tablicy numpy tak:

XYZV = [[1, 2, 3, 4], 
     [6, 7, 8, 9], 
     ... 
     [4, 5, 6, 7]] 

punkty danych nie są równomiernie rozłożone w przestrzeni XYZ i nie są przechowywane w określonej kolejności. Myślę, że w przykładzie użyto siatki mesh do generowania punktów danych - sprawdziłem to, ale zupełnie tego nie rozumiem. Każda pomoc byłaby doceniona?

H http://www.sethanil.com/_/rsrc/1267943775903/python-for-reseach/5/Article5-fig3.png

+0

Pokaż nam, co próbowałeś do tej pory. Będziemy tam pomagać. –

+0

Tylko na przyszłość, pytania takie jak ta są idealne dla [scicomp.SE]. –

Odpowiedz

9

Sztuką jest interpolacja nad siatkę przed działki - użyję scipy do tego. Poniżej R znajduje się (500,3) tablica wartości XYZ, a V to "wielkość" w każdym punkcie XYZ.

from scipy.interpolate import griddata 
import numpy as np 

# Create some test data, 3D gaussian, 200 points 
dx, pts = 2, 100j 

N = 500 
R = np.random.random((N,3))*2*dx - dx 
V = np.exp(-((R**2).sum(axis=1))) 

# Create the grid to interpolate on 
X,Y,Z = np.mgrid[-dx:dx:pts, -dx:dx:pts, -dx:dx:pts] 

# Interpolate the data 
F = griddata(R, V, (X,Y,Z)) 

Stąd jest to bardzo proste, aby wyświetlić nasze dane:

from mayavi.mlab import * 
contour3d(F,contours=8,opacity=.2) 

To daje ładny (lumpy) Gaussa.

enter image description here

Spójrz na docs dla griddata pamiętać, że można zmienić metodę interpolacji. Jeśli masz więcej punktów (zarówno na interpolowanej siatce, jak i na zestawie danych), interpolacja staje się lepsza i lepiej reprezentuje podstawową funkcję, którą próbujesz zilustrować. Oto Powyższy przykład przy 10K punktów i drobniejsza siatka:

enter image description here

+0

Dziękuję bardzo. To działa jak urok! Tylko jedno pytanie: jeśli chciałbym podwoić ilość punktów na siatce montażowej, co by się zmieniło w linii "dx, pts = 2, 100j"? – joshlk

+0

@Już zmienisz go na 'dx, pts = 2, 200j', jednak to podwoiłoby liczbę punktów w _acych wymiarach_, więc miałbyś 2^3 = 8 razy więcej punktów do interpolacji. 'dx' kontroluje zasięg siatki działek. Aby uzyskać dokładniejszą kontrolę, wystarczy 'mgrid' dla każdego wymiaru liniowego. – Hooked

+0

Uważam, że obliczenie funkcji griddata może zająć bardzo dużo czasu. Czy znasz jakieś wskazówki dotyczące przyspieszenia tego procesu? – joshlk

4

Można użyć filtru delaunay3d tworzyć komórki przed punktami. Następnie możesz utworzyć iso_surface() dla wyjścia UnstructuredGrid delaunay3d. Jeśli chcesz ImageData, możesz użyć filtru image_data_probe.

import numpy as np 
from tvtk.api import tvtk 
from mayavi import mlab 

points = np.random.normal(0, 1, (1000, 3)) 
ug = tvtk.UnstructuredGrid(points=points) 
ug.point_data.scalars = np.sqrt(np.sum(points**2, axis=1)) 
ug.point_data.scalars.name = "value" 
ds = mlab.pipeline.add_dataset(ug) 
delaunay = mlab.pipeline.delaunay3d(ds) 
iso = mlab.pipeline.iso_surface(delaunay) 
iso.actor.property.opacity = 0.1 
iso.contour.number_of_contours = 10 
mlab.show() 

enter image description here

+0

Witam, kiedy używam tej metody z własnymi danymi, ciągle pojawia się mnóstwo błędów pojawiających się w nowym oknie z ostatnim powiedzeniem: "Ostrzeżenie: W języku C: \ pisi \ tmp \ VTK-5.6.0-2 \ work \ VTK \ Graphics \ vtkDelaunay3D.cxx, linia 488 vtkDelaunay3D (03AD2250): Napotkano 27 zdegenerowanych trójkątów, podejrzane o jakość siatki ". Czy wiesz, co się dzieje? – joshlk