2010-11-02 21 views
14

Vorrei utilizzare Matplotlib per generare una trama a dispersione con un'enorme quantità di dati (circa 3 milioni di punti). In realtà ho 3 vettori con la stessa dimensione e io uso per tracciare nel modo seguente.Trama dispersa con un'enorme quantità di dati

import matplotlib.pyplot as plt 
import numpy as np 
from numpy import * 
from matplotlib import rc 
import pylab 
from pylab import * 
fig = plt.figure() 
fig.subplots_adjust(bottom=0.2) 
ax = fig.add_subplot(111) 
plt.scatter(delta,vf,c=dS,alpha=0.7,cmap=cm.Paired) 

Niente di speciale in realtà. Ma ci vuole troppo tempo per generarlo (sto lavorando sul mio MacBook Pro 4 GB di RAM con Python 2.7 e Matplotlib 1.0). C'è un modo per migliorare la velocità?

+0

Oltre decine di migliaia di punti, potrebbe essere preferibile una qualche forma di rappresentazione grafica raster sia per la velocità che per l'effettiva fruibilità. –

+0

Devi scegliere una risposta e contrassegnarla come accettata. – levesque

risposta

7

Si potrebbe prendere l'approccio heatmap mostrato here . In questo esempio, il colore rappresenta la quantità di dati nel contenitore, non il valore mediano dell'array dS, ma dovrebbe essere facile da modificare. Più tardi se sei interessato.

+0

ma, la mappa di calore non è una buona idea per il rilevamento di anomalie utilizzando la trama a dispersione. –

+0

@ChHaXam Buon punto. Puoi, tuttavia, sovrapporre un grafico a dispersione (di valori anomali) sopra la mappa di calore e ottenere il meglio da entrambi. – Paul

18

A meno che la grafica non sia enorme, molti di quei 3 milioni di punti si sovrappongono. (Un'immagine 400x600 240K ha solo puntini ...)

Quindi la cosa più semplice da fare sarebbe quella di prendere un campione di dire, 1000 punti, dai dati:

import random 
delta_sample=random.sample(delta,1000) 

e proprio trama che .

Ad esempio:

import matplotlib.pyplot as plt 
import matplotlib.cm as cm 
import numpy as np 
import random 

fig = plt.figure() 
fig.subplots_adjust(bottom=0.2) 
ax = fig.add_subplot(111) 

N=3*10**6 
delta=np.random.normal(size=N) 
vf=np.random.normal(size=N) 
dS=np.random.normal(size=N) 

idx=random.sample(range(N),1000) 

plt.scatter(delta[idx],vf[idx],c=dS[idx],alpha=0.7,cmap=cm.Paired) 
plt.show() 

alt text

Oppure, se avete bisogno di prestare maggiore attenzione ai valori anomali, allora forse si potrebbe bin i dati utilizzando np.histogram, e poi comporre un delta_sample che ha rappresentanti ogni cestino

Sfortunatamente, quando si utilizza np.histogram non penso che ci sia un modo semplice per associare i raccoglitori ai singoli punti di dati. Una soluzione semplice, ma approssimativa è quello di utilizzare la posizione di un punto nel o sul bordo bin sé come proxy per i punti in esso:

xedges=np.linspace(-10,10,100) 
yedges=np.linspace(-10,10,100) 
zedges=np.linspace(-10,10,10) 
hist,edges=np.histogramdd((delta,vf,dS), (xedges,yedges,zedges)) 
xidx,yidx,zidx=np.where(hist>0) 
plt.scatter(xedges[xidx],yedges[yidx],c=zedges[zidx],alpha=0.7,cmap=cm.Paired) 
plt.show() 

alt text

+0

Per completare la soluzione, se si dovesse campionare casualmente farlo N volte per ottenere l'intera immagine della situazione. –

+0

In realtà penso anche che i dati di binning potrebbero essere il modo più semplice. Puoi per favore suggerirmi come realizzarlo (conservando la corrispondenza tra i bidoni dei tre vettori? Voglio dire una specie di istogramma 3D) –

+0

grazie mille. In realtà penso di non aver spiegato correttamente me stesso. Vorrei creare una mappa di colori in modo che i colori indichino i valori medi delle variabili z nel cestino (xbin, ybin) per poterlo rappresentare come una rappresentazione. Questo è diverso penso rispetto a np.histogramdd. Forse qualcuno potrebbe aiutarmi a –

8

Che ne dici di provare pyplot.hexbin? Genera una sorta di mappa termica basata sulla densità dei punti in un determinato numero di bin.

Problemi correlati