web-dev-qa-db-fra.com

Faire le contour de la dispersion

En python, si j'ai un ensemble de données

x, y, z

Je peux faire un scatter avec

import matplotlib.pyplot as plt
plt.scatter(x,y,c=z)

Comment puis-je obtenir une plt.contourf(x,y,z) de la dispersion?

20
JuanPablo

Vous pouvez utiliser tricontourf comme suggéré dans le cas b. de cette autre réponse :

import matplotlib.tri as tri
import matplotlib.pyplot as plt

plt.tricontour(x, y, z, 15, linewidths=0.5, colors='k')
plt.tricontourf(x, y, z, 15)

Ancienne réponse:

Utilisez la fonction suivante pour convertir au format requis par contourf:

from numpy import linspace, meshgrid
from matplotlib.mlab import griddata

def grid(x, y, z, resX=100, resY=100):
    "Convert 3 column data to matplotlib grid"
    xi = linspace(min(x), max(x), resX)
    yi = linspace(min(y), max(y), resY)
    Z = griddata(x, y, z, xi, yi)
    X, Y = meshgrid(xi, yi)
    return X, Y, Z

Vous pouvez maintenant:

X, Y, Z = grid(x, y, z)
plt.contourf(X, Y, Z)

enter image description here

30
elyase

La solution dépendra de l'organisation des données.

Données sur réseau régulier

Si les données x et y définissent déjà une grille, elles peuvent être facilement remodelées en une grille quadrilatérale. Par exemple.

#x  y  z
 4  1  3
 6  1  8
 8  1 -9
 4  2 10
 6  2 -1
 8  2 -8
 4  3  8
 6  3 -9
 8  3  0
 4  4 -1
 6  4 -8
 8  4  8 

peut être tracé comme contour en utilisant

import matplotlib.pyplot as plt
import numpy as np
x,y,z = np.loadtxt("data.txt", unpack=True)
plt.contour(x.reshape(4,3), y.reshape(4,3), z.reshape(4,3))

Données arbitraires

une. Interpolation

Dans le cas où les données ne vivent pas sur une grille quadrilatérale, on peut interpoler les données sur une grille. Une façon de le faire est scipy.interpolate.griddata

import numpy as np
from scipy.interpolate import griddata

xi = np.linspace(4, 8, 10)
yi = np.linspace(1, 4, 10)
zi = griddata((x, y), z, (xi[None,:], yi[:,None]), method='linear')
plt.contour(xi, yi, zi)

b. Contour non quadrillé

Enfin, on peut tracer un contour complètement sans utiliser de grille quadrilatérale. Cela peut être fait en utilisant tricontour .

plt.tricontour(x,y,z)

Un exemple comparant les deux dernières méthodes se trouve sur la page matplotlib .

contour attend des données régulièrement maillées. Vous devez donc d'abord interpoler vos données:

import numpy as np
from scipy.interpolate import griddata
import matplotlib.pyplot as plt
import numpy.ma as ma
from numpy.random import uniform, seed
# make up some randomly distributed data
seed(1234)
npts = 200
x = uniform(-2,2,npts)
y = uniform(-2,2,npts)
z = x*np.exp(-x**2-y**2)
# define grid.
xi = np.linspace(-2.1,2.1,100)
yi = np.linspace(-2.1,2.1,100)
# grid the data.
zi = griddata((x, y), z, (xi[None,:], yi[:,None]), method='cubic')
# contour the gridded data, plotting dots at the randomly spaced data points.
CS = plt.contour(xi,yi,zi,15,linewidths=0.5,colors='k')
CS = plt.contourf(xi,yi,zi,15,cmap=plt.cm.jet)
plt.colorbar() # draw colorbar
# plot data points.
plt.scatter(x,y,marker='o',c='b',s=5)
plt.xlim(-2,2)
plt.ylim(-2,2)
plt.title('griddata test (%d points)' % npts)
plt.show()

Notez que j'ai volé sans vergogne ce code à l'excellent livre de recettes matplotlib

6
David Zwicker