2014-11-18 24 views
8

Ho dati in formato X, Y, Z in cui tutti sono array 1D e Z è l'ampiezza della misurazione in coordinate (X, Y). Mi piacerebbe mostrare questi dati come un contorno o una trama "imshow" in cui i contorni/colore rappresentano il valore Z (ampiezza).Contorno/rappresentazione grafica per dati X Y Z irregolari

La griglia per le misurazioni e l'aspetto X e Y sono irregolarmente distanziati.

Molte grazie,

len (X) = 100

len (Y) = 100

len (Z) = 100

+0

Forse duplicato di: http://stackoverflow.com/questions/3242382/interpolation-over-an-irregular-grid –

+0

hai provato qualcosa? hai qualche errore? –

+0

L'attenzione dell'altro post è principalmente sull'interpolazione dei dati irregolari in 2D. Non ho bisogno/voglio l'interpolazione. – Scientist

risposta

22

Vuol plt.tricontourf(x,y,z) soddisfare le vostre esigenze?

Rappresenterà i contorni riempiti per i dati con spaziatura irregolare (griglia non rettilinea).

Si potrebbe anche voler esaminare 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

+0

sì, certo, ma la trama è troppo dura. Sto cercando dei modi per farlo sembrare più liscio. Grazie! – Scientist

+0

@Scientist, quando uso tripcolor e lo faccio anche a tracciare i punti (casuali) che ho generato, vedo che non può essere più preciso: viene eseguita una triangolazione corretta e queste patch vengono poi riempite in base ai valori nei nodi del triangoli. –

+0

Oliver, grazie per il tuo contributo. Spingerò e vedrò se posso riorganizzare gli array 1-D in modo che plt.contour possa usarlo. – Scientist

0
xx, yy = np.meshgrid(x, y) 

plt.contour(xx, yy, z) 

non importa se sono distanziate irregolarmente, contorno e appezzamenti 3d richiedono un meshgrid.

+1

Z deve essere bidimensionale in questo caso. Non funziona con gli array 1-D. – Scientist

+0

Sei sicuro di non volere una trama lines3d? Sembra più simile a ciò che i tuoi dati sono costruiti per il –

+0

positivo. Ho bisogno di una trama di contorno. Quando dico che sono array 1-D, non sto dicendo che tutti gli elementi sono ordinati e rappresentano una linea. x-y formano una bella griglia con una spaziatura uniforme, con ogni punto che ha un valore Z corrispondente. – Scientist

2

(codice sorgente @ alla fine ...)

Ecco un po 'di piacere per gli occhi che ho prodotto giocare con questo un po'. Esplora il fatto che una trasformazione lineare di un meshgrid è ancora una meshgrid. Cioè a sinistra di tutti i miei grafici, sto lavorando con le coordinate X e Y per una funzione 2-d (input). A destra, voglio lavorare con le coordinate (AVG (X, Y), Y-X) per la stessa funzione.

Ho giocato con le meshgrid in coordinate native e trasformandole in meshgrid per le altre coordinate. Funziona bene se la trasformazione è lineare.

Per i due grafici in basso, ho lavorato con il campionamento casuale per indirizzare direttamente la domanda.

Ecco le immagini con setlims=False: enter image description here

E lo stesso con 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() 
0

Beh, se siete disposti a deviare dal Python in suo concorrente, R, ho appena presentato un pacchetto a CRAN (dovrebbe essere disponibile domani o il giorno successivo), che esegue il contouring su griglie non regolari - il seguente può essere ottenuto in poche righe di codice:

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

che produce il seguente:

example

Se si desidera una griglia più regolare, e può permettersi un po 'di tempo di calcolo in più:

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

I bordi sfocati di cui sopra, so come risolvere e dovrebbero essere risolti per th e la prossima versione del software ....

Problemi correlati