web-dev-qa-db-fra.com

Tracé de contour/imshow pour données X Y Z irrégulières

J'ai des données au format X, Y, Z où tous sont des tableaux 1D et Z est l'amplitude de la mesure à la coordonnée (X, Y). J'aimerais afficher ces données sous forme de contour ou de tracé 'imshow' où les contours/couleur représentent la valeur Z (amplitude).

La grille pour les mesures et l'aspect X et Y sont irrégulièrement espacées.

Merci beaucoup,

len (X) = 100

len (Y) = 100

len (Z) = 100

15
Scientist

plt.tricontourf(x,y,z) répond-il à vos exigences?

Il trace les contours remplis pour les données espacées irrégulièrement (grille non rectiligne).

Vous voudrez peut-être aussi vous pencher sur plt.tripcolor().

import numpy as np
import matplotlib.pyplot as plt
x = np.random.Rand(100)
y = np.random.Rand(100)
z = np.sin(x)+np.cos(y)
f, ax = plt.subplots(1,2, sharex=True, sharey=True)
ax[0].tripcolor(x,y,z)
ax[1].tricontourf(x,y,z, 20) # choose 20 contour levels, just to show how good its interpolation is
ax[1].plot(x,y, 'ko ')
ax[0].plot(x,y, 'ko ')
plt.savefig('test.png')

tripcolor and tricontourf example

39
Oliver W.

(Code source à la fin ...)

Voici un peu de bonbon pour les yeux que j'ai produit en jouant un peu avec cela. Il explore le fait qu'une transformation linéaire d'un maillage est toujours un maillage. C'est à dire. sur la gauche de toutes mes parcelles, je travaille avec les coordonnées X et Y pour une fonction 2-d (entrée). Sur la droite, je souhaite utiliser les coordonnées (AVG (X, Y), Y-X) pour la même fonction.

Je me suis amusé à créer des maillages en coordonnées natives et à les transformer en maillages pour les autres coordonnées. Fonctionne bien si la transformation est linéaire.

Pour les deux graphiques du bas, j'ai utilisé l'échantillonnage aléatoire pour répondre directement à votre question.

Voici les images avec setlims=False: enter image description here

Et la même chose avec setlims=True: enter image description here

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns

def f(x, y):
    return y**2 - x**2
lim = 2
xlims = [-lim , lim]
ylims = [-lim, lim]

setlims = False

pde = 1
numpts = 50
numconts = 20

xs_even = np.linspace(*xlims, num=numpts)
ys_even = np.linspace(*ylims, num=numpts)

xs_Rand = np.random.uniform(*xlims, size=numpts**2)
ys_Rand = np.random.uniform(*ylims, size=numpts**2)

XS_even, YS_even = np.meshgrid(xs_even, ys_even)

levels = np.linspace(np.min(f(XS_even, YS_even)), np.max(f(XS_even, YS_even)), num=numconts)

cmap = sns.blend_palette([sns.xkcd_rgb['cerulean'], sns.xkcd_rgb['purple']], as_cmap=True)

fig, axes = plt.subplots(3, 2, figsize=(10, 15))

ax = axes[0, 0]
H = XS_even
V = YS_even
Z = f(XS_even, YS_even)
ax.contour(H, V, Z, levels, cmap=cmap)
ax.plot(H.flatten()[::pde], V.flatten()[::pde], linestyle='None', marker='.', color='.75', alpha=0.5, zorder=1, markersize=4)
if setlims:
    ax.set_xlim([-lim/2., lim/2.])
    ax.set_ylim([-lim/2., lim/2.])
ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_title('Points on grid, contour')

ax = axes[1, 0]
H = H.flatten()
V = V.flatten()
Z = Z.flatten()
ax.tricontour(H, V, Z, levels, cmap=cmap)
ax.plot(H.flatten()[::pde], V.flatten()[::pde], linestyle='None', marker='.', color='.75', alpha=0.5, zorder=1, markersize=4)
if setlims:
    ax.set_xlim([-lim/2., lim/2.])
    ax.set_ylim([-lim/2., lim/2.])
ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_title('Points on grid, tricontour')

ax = axes[0, 1]
H = (XS_even + YS_even) / 2.
V = YS_even - XS_even
Z = f(XS_even, YS_even)
ax.contour(H, V, Z, levels, cmap=cmap)
ax.plot(H.flatten()[::pde], V.flatten()[::pde], linestyle='None', marker='.', color='.75', alpha=0.5, zorder=1, markersize=4)
if setlims:
    ax.set_xlim([-lim/2., lim/2.])
    ax.set_ylim([-lim, lim])
ax.set_xlabel('AVG')
ax.set_ylabel('DIFF')
ax.set_title('Points on transformed grid, contour')

ax = axes[1, 1]
H = H.flatten()
V = V.flatten()
Z = Z.flatten()
ax.tricontour(H, V, Z, levels, cmap=cmap)
ax.plot(H.flatten()[::pde], V.flatten()[::pde], linestyle='None', marker='.', color='.75', alpha=0.5, zorder=1, markersize=4)
if setlims:
    ax.set_xlim([-lim/2., lim/2.])
    ax.set_ylim([-lim, lim])
ax.set_xlabel('AVG')
ax.set_ylabel('DIFF')
ax.set_title('Points on transformed grid, tricontour')

ax=axes[2, 0]
H = xs_Rand
V = ys_Rand
Z = f(xs_Rand, ys_Rand)
ax.tricontour(H, V, Z, levels, cmap=cmap)
ax.plot(H[::pde], V[::pde], linestyle='None', marker='.', color='.75', alpha=0.5, zorder=1, markersize=4)
if setlims:
    ax.set_xlim([-lim/2., lim/2.])
    ax.set_ylim([-lim/2., lim/2.])
ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_title('Points random, tricontour')

ax=axes[2, 1]
H = (xs_Rand + ys_Rand) / 2.
V = ys_Rand - xs_Rand
Z = f(xs_Rand, ys_Rand)
ax.tricontour(H, V, Z, levels, cmap=cmap)
ax.plot(H[::pde], V[::pde], linestyle='None', marker='.', color='.75', alpha=0.5, zorder=1, markersize=4)
if setlims:
    ax.set_xlim([-lim/2., lim/2.])
    ax.set_ylim([-lim, lim])
ax.set_xlabel('AVG')
ax.set_ylabel('DIFF')
ax.set_title('Points random transformed, tricontour')

fig.tight_layout()
2
8one6
xx, yy = np.meshgrid(x, y)

plt.contour(xx, yy, z)

Peu importe si elles sont irrégulièrement espacées, les courbes de niveau et 3D nécessitent un maillage.

0
Adam Hughes

Eh bien, si vous êtes prêt à passer de Python à son concurrent, R, je viens de soumettre un paquet au CRAN (qui devrait être disponible demain ou le lendemain), qui effectue le contournement sur des grilles non régulières. quelques lignes de code:

library(contoureR)
set.seed(1)
x = runif(100)
y = runif(100)
z = sin(x) + cos(y)
df = getContourLines(x,y,z,binwidth=0.0005)
ggplot(data=df,aes(x,y,group=Group)) + 
  geom_polygon(aes(fill=z)) + 
  scale_fill_gradient(low="blue",high="red") + 
  theme_bw()

Qui produit les éléments suivants:

 example

Si vous voulez une grille plus régulière et que vous pouvez vous permettre un peu de temps de calcul supplémentaire:

x = seq(0,1,by=0.005)
y = seq(0,1,by=0.005)
d = expand.grid(x=x,y=y)
d$z = with(d,sin(x) + cos(y))
df = getContourLines(d,binwidth=0.0005)
ggplot(data=df,aes(x,y,group=Group)) + 
  geom_polygon(aes(fill=z)) + 
  scale_fill_gradient(low="blue",high="red") + 
  theme_bw()

 example2

Les bords flous dans ce qui précède, je sais comment résoudre et devrait être corrigé pour la prochaine version du logiciel ....

0
Nicholas Hamilton