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
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')
(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
:
Et la même chose avec setlims=True
:
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()
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.
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:
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()
Les bords flous dans ce qui précède, je sais comment résoudre et devrait être corrigé pour la prochaine version du logiciel ....