2012-01-25 12 views
25

Mam prosty problem w python i matplotlib. Mam 3 listy: x, yi rho z rho [i] gęstość w punkcie x [i], y [i]. Wszystkie wartości x i y są między -1. i 1. ale nie są w określonej kolejności.Python: 2d wykres konturu z 3 list: x, yi rho?

Jak utworzyć wykres konturu (jak z imshow) gęstości rho (interpolowana w punktach x, y).

Dziękuję bardzo.

EDIT: Ja pracuję z dużymi tablicami: X, Y i rho mają między 10.000 a 1.000.000 elementy

+0

zrobił kod akceptowane pracował dla Ciebie? Mam taki sam spis list, ale nie mogę go rozwiązać. – diffracteD

Odpowiedz

39

Należy interpolować swoje wartości rho. Nie ma jednego sposobu, aby to zrobić, a "najlepsza" metoda zależy całkowicie od informacji a priori, którą powinieneś włączyć do interpolacji.

Zanim jednak przejdę do rantu w metodach interpolacji "czarnej skrzynki", radialna funkcja podstawowa (np. "Spline-splajn" jest szczególnym rodzajem funkcji radialnej) jest często dobrym wyborem. Jeśli masz miliony punktów, to realizacja będzie nieefektywne, ale jako punkt wyjścia:

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

Bardzo interesująca metoda, ale nie działa z dużymi tablicami: x, yi rho mają około 10000 elementów ... – Vincent

+0

Nadal można używać Rbf dla dużych tablic, wystarczy tylko uwzględnić pobliskie punkty. Jeszcze trochę dodam przykład. Alternatywnie, jeśli nie chcesz faktycznie próbkować wszystkiego na zwykłej siatce, możesz użyć triangulacji delaunay do rysowania konturów (co jest po prostu bardzo prostą i niezbyt gładką formą interpolacji). Przy tak wielu punktach bardziej praktyczne jest użycie lokalnej metody interpolacji. –

+0

@JoeKington Witam, mam problem z powyższym kodem, Mój zestaw danych składa się z list x, yiz. x i y różnią się niezależnie, z zmienia się w zależności od (x, y). 'x = (1.2 to 2.5)', 'y = (90 do 180)' i 'z = (5 do -5)'. Jeśli spróbuję powyższego kodu z moim zestawem danych, otrzymam zwinięty wykres (nic wzdłuż osi X). Proszę pomóż. – diffracteD

11

Można wykorzystać griddata (wymaga scipy> = 0,10), jest to metoda triangulacji opartej scipy za .

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() 

Istnieje również odwrotna odległość ważył interpolacji - podobny do RBF, ale powinien działać lepiej dla dużych # punktów: Inverse Distance Weighted (IDW) Interpolation with Python

Powiązane problemy