2012-05-26 27 views
7

Tengo un gran conjunto de datos que trato de representar en 3D con la esperanza de detectar un patrón. He pasado bastante tiempo leyendo, investigando y codificando, pero luego me di cuenta de que mi principal problema NO es la programación, sino que realmente el está eligiendo una forma de visualizar los datos.¿Cómo representaría los siguientes datos 3D en Matplotlib o Mayavi?

El mplot3d de Matplotlib ofrece muchas opciones (estructura alámbrica, contorno, contorno relleno, etc.), y también lo hace MayaVi. Pero hay tantas opciones (y cada una con su propia curva de aprendizaje) que estoy prácticamente perdido y no sé por dónde empezar. Entonces, mi pregunta es, en esencia, ¿qué método de trazado utilizarías si tuvieras que lidiar con estos datos?

Mis datos se basan en fechas. Para cada punto en el tiempo, trazado un valor (la lista 'Actual').

Pero para cada punto en el tiempo, también tengo un límite superior, un límite inferior y un punto de rango medio. Estos límites y puntos medios se basan en una semilla, en diferentes planos.

Quiero ver el punto o identificar el patrón cuando, o antes, ocurre un cambio importante en mi lectura 'Actual'. ¿Es cuando se encuentran los límites superiores en todos los planos? ¿O acercarse el uno al otro? ¿Es cuando el valor real toca un límite superior/medio/inferior? ¿Es cuando los Uppers en un solo plano tocan los Lowers de otro avión?

En el código que estoy pegando, he reducido el conjunto de datos a solo unos pocos elementos. Solo estoy usando gráficos simples de dispersión y de línea, pero debido al tamaño del conjunto de datos (¿y quizás las limitaciones de mplot3d?), No puedo usarlo para detectar las tendencias que estoy buscando.

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

Estoy recibiendo esta trama, pero simplemente no me ayuda a ver ninguna correlación.

enter image description here No soy matemático ni científico, entonces lo que realmente necesito es ayuda para elegir el FORMATO en el que visualizar mis datos. ¿Hay alguna manera efectiva de mostrar esto en mplot3d? ¿O usarías MayaVis? En cualquier caso, ¿qué biblioteca y clase usarías?

Gracias de antemano.

+2

Si está buscando correlaciones, 3d puede no ser la mejor manera. La perspectiva se interpone en el camino de la interpretación. Es posible que desee utilizar gráficos facetados, sobre trazado y diagramas de dispersión en su lugar. – gauden

Respuesta

7

Para comentar la parte de visualización de su pregunta (no la programación), me he burlado de algunos ejemplos de gráficos facetados para sugerir alternativas que puede utilizar para explorar sus datos.

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

En el primer ejemplo, la delgada línea azul es el valor real superpuesta en los tres niveles en cada uno de los ejes 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

En el segundo conjunto, cada panel tiene un diagrama de dispersión del valor real contra los tres niveles (superior, medio, bajo) en cada uno de los ejes 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

Gracias, gauden. Con respecto al segundo conjunto (el que tiene un sobre gris que rodea la trama), ¿qué es este tipo de cuadro conocido como R? ¿Y sabrías el nombre del equivalente de Python/matplotlib? He estado buscando en [la galería de matplotlib] (http://matplotlib.sourceforge.net/gallery.html) y parece que no encuentro nada similar. – Zambi

+1

@Zambi Me complace publicar el código R. Es posible que desee agregar la etiqueta 'R' a su pregunta para agregarla al número de posibles respuestas. No estoy seguro de que el segundo argumento tenga un nombre específico. Es un conjunto de diagramas de dispersión facetados por dos variables (eje z y niveles). La línea es una curva 'loess' ajustada y la nube representa el error estándar. Uso el paquete ['ggplot2'] (http://had.co.nz/ggplot2/) para producir esto. – gauden

+2

Algunos nombres comunes para este enfoque de dividir datos en subconjuntos y trazar una grilla de subparcelas 2D son "facetas" (ggplot [Wickham]) o "pequeños múltiplos" (Tufte) o "gráficos de acondicionamiento", a menudo acortados a "coplots" (celosía/Trellis [Cleveland, Chambers, Sarkar]) –

2

Gracias, Gauden. De hecho, R fue parte de mi investigación, y lo he instalado, pero no fui lo suficientemente lejos con el tutorial. A menos que esté en contra de las reglas de StackOverFlow, apreciaría ver ese código R suyo.

Ya he intentado las representaciones 2D, pero en muchos casos los valores para Tops1/Tops2/Tops3 (y de manera similar para Lows) serían iguales, por lo que las líneas terminan superponiéndose y oscureciéndose entre sí. Es por eso que estoy probando la opción 3D. Su idea de 3 paneles de gráficos 2D es una gran sugerencia que no había explorado.

Voy a intentarlo, pero hubiera pensado que una trama 3D me daría una idea más clara, especialmente una trama de malla/alambre que mostraría valores convergentes y vería el punto azul flotando en el espacio 3D en el punto en que las líneas de la estructura comienzan a hacer un pico o un valle. Simplemente no puedo hacer que funcione.

He intentado adaptar matplotlib's Wireframe example pero la trama que obtengo no se parece en absoluto a una estructura alámbrica.

Esto es lo que recibo de la código de abajo enter image description here con sólo dos de los elementos de datos (Tops1 y 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 para la experimentación. Espero que otros intervienen para ayudar y he favorecido la pregunta para ver qué emerge. – gauden

Cuestiones relacionadas