2012-02-23 8 views
8

desidero fare una trama di contorno 3D utilizzando Mayavi esattamente allo stesso modo del terzo figura in questa pagina (un modello nuvola elettronica idrogeno):grafico 3D contorno da dati utilizzando Mayavi/Python

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

Ho un set di punti dati che ho creato usando il mio modello che vorrei usare. I punti di dati sono memorizzati in una matrice NumPy multidimensionale modo:

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

i punti di dati non sono uniformemente distribuite nello spazio XYZ e non memorizzati in un ordine particolare. Penso che l'esempio usi un meshgrid per generare i punti di dati: l'ho cercato ma non lo capisco assolutamente. Qualsiasi aiuto sarebbe molto apprezzato?

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

+0

mostrarci, cosa hai provato finora. Aiuteremo da lì in poi. –

+0

Solo per riferimenti futuri, domande come questa sono ideali per [scicomp.SE]. –

risposta

9

Il trucco è quello di interpolare su una griglia prima di trama - userei scipy per questo. Sotto R c'è una matrice (500,3) di valori XYZ e V è la "grandezza" in ciascun punto 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)) 

da qui è un gioco da ragazzi per visualizzare i nostri dati:

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

Questo dà un bel (grumoso) gaussiana.

enter image description here

Date un'occhiata alla documentazione per griddata, si noti che è possibile modificare il metodo di interpolazione. Se si hanno più punti (sia sulla griglia interpolata che sul set di dati), l'interpolazione migliora e rappresenta meglio la funzione sottostante che si sta tentando di illustrare. Ecco l'esempio di cui sopra a 10K punti e una griglia più fine:

enter image description here

+0

Grazie mille. Esso funziona magicamente! Solo una domanda: se volessi raddoppiare la quantità di punti sulla griglia di montaggio, cosa cambierei nella riga 'dx, pts = 2, 100j'? – joshlk

+0

@Josh lo cambieresti in 'dx, pts = 2, 200j', tuttavia questo raddoppierà il numero di punti in _each dimension_ in modo da avere 2^3 = 8 volte il numero di punti da interpolare sopra. 'dx' controlla l'estensione della griglia trama. Per un controllo più preciso basta 'mgrid' per ogni dimensione lineare. – Hooked

+0

Trovo che la funzione di griddata possa richiedere molto tempo per il calcolo. Conosci qualche consiglio per accelerare il processo? – joshlk

4

È possibile utilizzare il filtro delaunay3d per creare cellule da punti. Quindi puoi creare un iso_surface() per l'output UnstructuredGrid di delaunay3d. Se si desidera ImageData, è possibile utilizzare il filtro 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

Salve quando uso questo metodo con i miei dati continuo a ricevere un sacco di errori che appaiono in una nuova finestra con l'ultimo detto: "Attenzione: In C: \ pisi \ tmp \ VTK-5.6.0-2 \ work \ VTK \ Graphics \ vtkDelaunay3D.cxx, riga 488 vtkDelaunay3D (03AD2250): 27 triangoli degenerati rilevati, sospetto di qualità mesh ". Sai cosa sta succedendo? – joshlk