2012-01-25 12 views
25

Tengo un problema simple en python y matplotlib. Tengo 3 listas: x, y y rho con rho [i] una densidad en el punto x [i], y [i]. Todos los valores de xey están entre -1. y 1. pero no están en un orden específico.Python: trama de 2d curvas de 3 listas: x, y y rho?

Cómo hacer una gráfica de contorno (como con imshow) de la densidad rho (interpolada en los puntos x, y).

Muchas gracias.

EDIT: Yo trabajo con grandes conjuntos: X, Y y Rho tener entre 10.000 y 1.000.000 de elementos

+0

lo hace el código Usted ha aceptado trabajado para usted? Estoy teniendo el mismo tipo de escenario de lista pero no puedo resolverlo. – diffracteD

Respuesta

39

Es necesario interpolar los valores rho. No hay una sola forma de hacerlo, y el "mejor" método depende completamente de la información a priori que debe incorporar en la interpolación. Sin embargo, antes de entrar en una diatriba sobre métodos de interpolación de "caja negra", una función de base radial (por ejemplo, una "placa delgada-spline" es un tipo particular de función de base radial) es a menudo una buena elección. Si usted tiene millones de puntos, esta aplicación será ineficaz, sino como un punto de partida:

import numpy as np 
import matplotlib.pyplot as plt 
import scipy.interpolate 

# Generate data: 
x, y, z = 10 * np.random.random((3,10)) 

# Set up a regular grid of interpolation points 
xi, yi = np.linspace(x.min(), x.max(), 100), np.linspace(y.min(), y.max(), 100) 
xi, yi = np.meshgrid(xi, yi) 

# Interpolate 
rbf = scipy.interpolate.Rbf(x, y, z, function='linear') 
zi = rbf(xi, yi) 

plt.imshow(zi, vmin=z.min(), vmax=z.max(), origin='lower', 
      extent=[x.min(), x.max(), y.min(), y.max()]) 
plt.scatter(x, y, c=z) 
plt.colorbar() 
plt.show() 

enter image description here

+0

Método muy interesante pero no funciona con arreglos grandes: x, y y rho tienen alrededor de 10000 elementos ... – Vincent

+0

Aún puede usar un Rbf para matrices grandes, solo necesita incluir puntos cercanos. Agregaré un ejemplo en solo un poco. Alternativamente, si no quiere realmente muestrear todo en una cuadrícula regular, puede usar la triangulación delaunay para dibujar los contornos (que es simplemente una forma de interpolación muy simple y no particularmente suave). Con tantos puntos, sin embargo, es más práctico usar un método de interpolación local. –

+0

@JoeKington Hola, tengo un problema con este código anterior. Mi conjunto de datos consiste en las listas x, y y z. xey varían de forma independiente; z varía según (x, y). 'x = (1.2 a 2.5)', 'y = (90 a 180)' y 'z = (5 a -5)'. Si pruebo el código anterior con mi conjunto de datos obtendré un diagrama colapsado (nada a lo largo del eje x). Por favor ayuda. – diffracteD

11

Puede utilizar (requiere Scipy> = 0,10), que es un método basado en la triangulación de scipy griddata .

import numpy as np 
import matplotlib.pyplot as plt 
import scipy.interpolate 

# Generate data: for N=1e6, the triangulation hogs 1 GB of memory 
N = 1000000 
x, y = 10 * np.random.random((2, N)) 
rho = np.sin(3*x) + np.cos(7*y)**3 

# Set up a regular grid of interpolation points 
xi, yi = np.linspace(x.min(), x.max(), 300), np.linspace(y.min(), y.max(), 300) 
xi, yi = np.meshgrid(xi, yi) 

# Interpolate; there's also method='cubic' for 2-D data such as here 
zi = scipy.interpolate.griddata((x, y), rho, (xi, yi), method='linear') 

plt.imshow(zi, vmin=rho.min(), vmax=rho.max(), origin='lower', 
      extent=[x.min(), x.max(), y.min(), y.max()]) 
plt.colorbar() 
plt.show() 

También hay distancia inversa pesaba interpolación - similar a RBF, pero debería funcionar mejor para grandes # de puntos: Inverse Distance Weighted (IDW) Interpolation with Python