2012-05-26 28 views
7

Ho un grande insieme di dati che sto cercando di rappresentare in 3D nella speranza di individuare un modello. Ho passato un po 'di tempo a leggere, la ricerca e la codifica, ma poi ho capito il mio problema principale non è la programmazione, ma in realtà la scelta di un modo per visualizzare i dati.Come rappresenteresti i seguenti dati 3D in Matplotlib o Mayavi?

mplot3d di Matplotlib offre un sacco di opzioni (wireframe, contorno, contorno pieno, ecc), e così fa MayaVi. Ma ci sono così tante scelte (e ognuna con una propria curva di apprendimento) che sono praticamente perso e non so da dove cominciare! Quindi la mia domanda è essenzialmente quale metodo di tracciamento useresti se avessi a che fare con questi dati?

miei dati è la data-base. Per ogni punto nel tempo, traccio un valore (la lista 'Attuale').

Ma per ogni punto nel tempo, ho anche un limite superiore, un limite inferiore, e un punto di mid-range. Questi limiti e punti medi sono basati su un seme, in piani diversi.

voglio macchiare il punto o identificare il modello quando, o prima, un grande cambiamento avviene nella mia lettura 'Actual'. È quando i limiti superiori su tutti i piani si incontrano? O avvicinarsi l'un l'altro? È quando il valore effettivo tocca un limite superiore/medio/basso? È quando le Uppers in un piano toccano i Lowers di un altro piano?

Nel codice che sto incollando, ho ridotto il set di dati a pochi elementi. Sto solo usando semplici grafici a dispersione e linea, ma a causa delle dimensioni del set di dati (e forse dei limiti di mplot3d?), Non riesco a utilizzarlo per individuare le tendenze che sto cercando.

dates = [20110101,20110104,20110105,20110106,20110107,20110108,20110111,20110112] 

zAxis0= [  0,  0,  0,  0,  0,  0,  0,  0] 
Actual= [ 1132, 1184, 1177,  950, 1066, 1098, 1116, 1211] 

zAxis1= [  1,  1,  1,  1,  1,  1,  1,  1] 
Tops1 = [ 1156, 1250, 1156, 1187, 1187, 1187, 1156, 1156] 
Mids1 = [ 1125, 1187, 1125, 1156, 1156, 1156, 1140, 1140] 
Lows1 = [ 1093, 1125, 1093, 1125, 1125, 1125, 1125, 1125] 

zAxis2= [  2,  2,  2,  2,  2,  2,  2,  2] 
Tops2 = [ 1125, 1125, 1125, 1125, 1125, 1250, 1062, 1250] 
Mids2 = [ 1062, 1062, 1062, 1062, 1062, 1125, 1000, 1125] 
Lows2 = [ 1000, 1000, 1000, 1000, 1000, 1000,  937, 1000] 

zAxis3= [  3,  3,  3,  3,  3,  3,  3,  3] 
Tops3 = [ 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250] 
Mids3 = [ 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187] 
Lows3 = [ 1125, 1125, 1000, 1125, 1125, 1093, 1093, 1000] 

import matplotlib.pyplot 
from mpl_toolkits.mplot3d import Axes3D 

fig = matplotlib.pyplot.figure() 
ax = fig.add_subplot(111, projection = '3d') 

#actual values 
ax.scatter(dates, zAxis0, Actual, color = 'c', marker = 'o') 

#Upper limits, Lower limts, and Mid-range for the FIRST plane 
ax.plot(dates, zAxis1, Tops1, color = 'r') 
ax.plot(dates, zAxis1, Mids1, color = 'y') 
ax.plot(dates, zAxis1, Lows1, color = 'b') 

#Upper limits, Lower limts, and Mid-range for the SECOND plane 
ax.plot(dates, zAxis2, Tops2, color = 'r') 
ax.plot(dates, zAxis2, Mids2, color = 'y') 
ax.plot(dates, zAxis2, Lows2, color = 'b') 

#Upper limits, Lower limts, and Mid-range for the THIRD plane 
ax.plot(dates, zAxis3, Tops3, color = 'r') 
ax.plot(dates, zAxis3, Mids3, color = 'y') 
ax.plot(dates, zAxis3, Lows3, color = 'b') 

#These two lines are just dummy data that plots transparent circles that 
#occpuy the "wall" behind my actual plots, so that the last plane appears 
#floating in 3D rather than being pasted to the plot's background 
zAxis4= [  4,  4,  4,  4,  4,  4,  4,  4] 
ax.scatter(dates, zAxis4, Actual, color = 'w', marker = 'o', alpha=0) 

matplotlib.pyplot.show() 

che sto ricevendo questa trama, ma semplicemente non aiutarmi a vedere eventuali co-relazioni.

enter image description here Non sono un matematico o uno scienziato, quindi quello di cui ho veramente bisogno è aiutare a scegliere il FORMATO in cui visualizzare i miei dati. C'è un modo efficace per mostrare questo in mplot3d? O useresti MayaVis? In entrambi i casi, quale libreria e classe/i useresti?

Grazie in anticipo.

+2

Se siete alla ricerca di correlazioni, 3D non può essere il modo migliore. La prospettiva si intromette nell'interpretazione. Si consiglia di utilizzare invece i diagrammi sfaccettati, il tracciamento e i grafici a dispersione. – gauden

risposta

7

Per commentare la parte di visualizzazione della domanda (non la programmazione), ho preso in giro alcuni esempi di grafici sfaccettati per suggerire alternative che potreste voler utilizzare per esplorare i vostri dati.

library("lubridate") 
library("ggplot2") 
library("reshape2") 

dates <- c("2011-01-01","2011-01-04","2011-01-05", 
      "2011-01-06","2011-01-07","2011-01-08", 
      "2011-01-11","2011-01-12") 
dates <- ymd(dates) 

Actual<- c( 1132, 1184, 1177,  950, 1066, 1098, 1116, 1211, 
       1132, 1184, 1177,  950, 1066, 1098, 1116, 1211, 
       1132, 1184, 1177,  950, 1066, 1098, 1116, 1211) 
z  <- c(  1,  1,  1,  1,  1,  1,  1,  1, 
        2,  2,  2,  2,  2,  2,  2,  2, 
        3,  3,  3,  3,  3,  3,  3,  3) 
Tops <- c( 1156, 1250, 1156, 1187, 1187, 1187, 1156, 1156, 
       1125, 1125, 1125, 1125, 1125, 1250, 1062, 1250, 
       1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250) 
Mids <- c( 1125, 1187, 1125, 1156, 1156, 1156, 1140, 1140, 
       1062, 1062, 1062, 1062, 1062, 1125, 1000, 1125, 
       1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187) 
Lows <- c( 1093, 1125, 1093, 1125, 1125, 1125, 1125, 1125, 
       1000, 1000, 1000, 1000, 1000, 1000,  937, 1000, 
       1125, 1125, 1000, 1125, 1125, 1093, 1093, 1000) 

df <- data.frame(cbind(z, dates, Actual, Tops, Mids, Lows)) 

dfm <- melt(df, id.vars=c("z", "dates", "Actual")) 

Nel primo esempio, la linea blu sottile è il valore effettivo sovrapposto, tutti e tre i livelli in ciascuno degli assi z.

p <- ggplot(data = dfm, 
      aes(x = dates, 
       y = value, 
       group = variable, 
       colour = variable) 
      ) + geom_line(size = 3) + 
       facet_grid(variable ~ z) + 
       geom_point(aes(x = dates, 
           y = Actual), 
          colour = "steelblue", 
          size = 3) + 
           geom_line(aes(x = dates, 
              y = Actual), 
             colour = "steelblue", 
             size = 1) + 
              theme_bw() 
p 

line charts

Nel secondo set, ogni pannello ha una dispersione del valore effettivo contro i tre livelli (alto, medio, basso) in ciascuno degli assi z.

p <- ggplot(data = dfm, 
      aes(x = Actual, 
       y = value, 
       group = variable, 
       colour = variable) 
      ) + geom_point(size = 3) + 
       geom_smooth() + 
       facet_grid(variable ~ z) + 
       theme_bw() 
p 

correlation

+0

Grazie, gauden. Per quanto riguarda il secondo set (quello con una busta grigia che circonda la trama), qual è questo tipo di grafico noto come in R? E sapresti il ​​nome dell'equivalente Python/matplotlib? Ho visto [la galleria di matplotlib] (http://matplotlib.sourceforge.net/gallery.html) e non riesco a trovare nulla di simile. – Zambi

+1

@Zambi Sono lieto di pubblicare il codice R. Potresti voler aggiungere il tag 'R' alla tua domanda per aggiungere al numero di possibili risposte. Non sono sicuro che la seconda trama abbia un nome specifico. È un insieme di scatterplot sfaccettati da due variabili (asse z e livelli). La linea è una curva 'loess' adattata e la nuvola rappresenta l'errore standard. Io uso il pacchetto ['ggplot2'] (http://had.co.nz/ggplot2/) per produrre questo. – gauden

+2

Alcuni nomi comuni per questo approccio di spezzare i dati in sottoinsiemi e tracciare una griglia di sottotrame 2D sono "facet" (ggplot [Wickham]) o "piccoli multipli" (Tufte) o "trame di condizionamento", spesso abbreviate in "coplots" (reticolo/traliccio [Cleveland, Chambers, Sarkar]) –

2

Grazie, Gauden. R era in realtà parte della mia ricerca, e ho installato ma non sono andato abbastanza lontano con il tutorial. A meno che non sia contro le regole di StackOverFlow, mi farebbe piacere vedere il tuo codice R.

Ho già provato le rappresentazioni 2D, ma in molti casi i valori di Tops1/Tops2/Tops3 (e analogamente per Lows) sarebbero uguali, quindi le linee finiscono per sovrapporsi e oscurarsi a vicenda. Questo è il motivo per cui sto provando l'opzione 3D. La tua idea di 3 pannelli di grafici 2D è un ottimo suggerimento che non avevo esplorato.

Proverò, ma avrei pensato che una trama 3D mi avrebbe dato un'immagine più chiara, in particolare una trama wireframe/mesh che mostrava valori convergenti e vedrei il punto blu fluttuare nello spazio 3D nel punto in cui le linee sul wireframe iniziano a fare un picco o una depressione. Non riesco a farlo funzionare.

Ho provato ad adattare matplotlib's Wireframe example ma la trama che sto ottenendo non sembra affatto un wireframe.

Questo è quello che sto ricevendo dal codice qui sotto enter image description here con solo due degli elementi di dati (Tops1 e Tops2):

dates = [20110101,20110104,20110105,20110106,20110107,20110108,20110111,20110112] 

zAxis0= [  0,  0,  0,  0,  0,  0,  0,  0] 
Actual= [ 1132, 1184, 1177,  950, 1066, 1098, 1116, 1211] 

zAxis1= [  1,  1,  1,  1,  1,  1,  1,  1] 
Tops1 = [ 1156, 1250, 1156, 1187, 1187, 1187, 1156, 1156] 
Mids1 = [ 1125, 1187, 1125, 1156, 1156, 1156, 1140, 1140] 
Lows1 = [ 1093, 1125, 1093, 1125, 1125, 1125, 1125, 1125] 

zAxis2= [  2,  2,  2,  2,  2,  2,  2,  2] 
Tops2 = [ 1125, 1125, 1125, 1125, 1125, 1250, 1062, 1250] 
Mids2 = [ 1062, 1062, 1062, 1062, 1062, 1125, 1000, 1125] 
Lows2 = [ 1000, 1000, 1000, 1000, 1000, 1000,  937, 1000] 

zAxis3= [  3,  3,  3,  3,  3,  3,  3,  3] 
Tops3 = [ 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250] 
Mids3 = [ 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187] 
Lows3 = [ 1125, 1125, 1000, 1125, 1125, 1093, 1093, 1000] 

import matplotlib.pyplot 
from mpl_toolkits.mplot3d import Axes3D 

fig = matplotlib.pyplot.figure() 
ax = fig.add_subplot(111, projection = '3d') 

####example code from: http://matplotlib.sourceforge.net/mpl_toolkits/mplot3d/tutorial.html#wireframe-plots 
#from mpl_toolkits.mplot3d import axes3d 
#import matplotlib.pyplot as plt 
#import numpy as np 

#fig = plt.figure() 
#ax = fig.add_subplot(111, projection='3d') 
#X, Y, Z = axes3d.get_test_data(0.05) 
#ax.plot_wireframe(X, Y, Z, rstride=10, cstride=10) 

#plt.show() 

X, Y, Z = dates, Tops1, Tops2 
ax.plot_wireframe(X, Y, Z, rstride=1, cstride=1, color = 'g') 

matplotlib.pyplot.show() 
+0

+1 per la sperimentazione. Spero che altri intervengano per aiutare e ho preferito la domanda per vedere cosa emerge. – gauden