2012-01-23 10 views
8

dado un ggplot de, por ejemplo, puntos, ¿cómo averiguar la fila de datos que un punto dado correspondió a?¿Cómo relaciona ggplot2 grobs con los datos?

Una parcela de muestreo:

library(ggplot2) 
(p <- ggplot(mtcars, aes(mpg, wt)) + 
    geom_point() + 
    facet_wrap(~ gear) 
) 

podemos obtener el grobs que contienen puntos con grid.ls + grid.get.

grob_names <- grid.ls(print = FALSE)$name 
point_grob_names <- grob_names[grepl("point", grob_names)] 
point_grobs <- lapply(point_grob_names, grid.get) 

Esta última variable contiene detalles de las coordenadas x-y, y tamaño de punto, etc. (prueba unclass(point_grobs[[1]])), pero no es obvio cómo consigo la fila de datos en mtcars que cada punto corresponde a.


Para responder a la pregunta de por qué kohske estoy haciendo esto, estoy usando gridSVG para crear un diagrama de dispersión interactiva. Cuando pasa el mouse sobre un punto, quiero mostrar información contextual. En el ejemplo de mtcars, podría mostrar una información sobre herramientas con el nombre del automóvil u otros valores de esa fila del marco de datos.

Mi idea hacky hasta ahora es incluir una columna id como una etiqueta de texto invisible:

mtcars$id <- seq_len(nrow(mtcars)) 
p + geom_text(aes(label = id), colour = NA) 

A continuación, recorrer el árbol de grobs desde el punto Grob a la Grob texto, y mostrar la fila del conjunto de datos indexado por la etiqueta.

Ésta es incómoda y poco generalizable. Si hay una manera de almacenar el valor id dentro del punto grob, sería mucho más limpio.

+0

No hay salida fácil. ¿Cuál es tu objetivo final? Puede haber alternativas. – kohske

+0

@kohske: Demasiado tiempo para un comentario, por lo que he actualizado la pregunta para explicar lo que estoy haciendo. –

+0

Muy interesante. Entiendo tu propósito Lamentablemente, no tenemos forma de acceder a los datos a través de grob (incluso en la próxima versión, probablemente). Pero tal vez sea útil tener información sobre los datos (especialmente cuando 'stat =" identity "). Lo discutiré. – kohske

Respuesta

7

Este script genera un archivo SVG en donde se puede anotar de forma interactiva los puntos.

library(ggplot2) 
library(gridSVG) 

geom_point2 <- function (...) GeomPoint2$new(...) 
GeomPoint2 <- proto(GeomPoint, { 
    objname <- "point2" 
    draw <- function(., data, scales, coordinates, na.rm = FALSE, ...) { 
    data <- remove_missing(data, na.rm, c("x", "y", "size", "shape"), 
     name = "geom_point") 
    if (empty(data)) 
     return(zeroGrob()) 
    name <- paste(.$my_name(), data$PANEL[1], sep = ".") 
    with(coordinates$transform(data, scales), ggname(name, 
     pointsGrob(x, y, size = unit(size, "mm"), pch = shape, 
      gp = gpar(col = alpha(colour, alpha), fill = fill, label = label, 
       fontsize = size * .pt)))) 
    }} 
) 

p <- ggplot(mtcars, aes(mpg, wt, label = rownames(mtcars))) + geom_point2() + facet_wrap(~ gear) 
print(p) 

grob_names <- grid.ls(print = FALSE)$name 
point_grob_names <- sort(grob_names[grepl("point", grob_names)]) 
point_grobs_labels <- lapply(point_grob_names, function(x) grid.get(x)$gp$label) 

library(rjson) 
jlabel <- toJSON(point_grobs_labels) 

grid.text("value", 0.05, 0.05, just = c(0, 0), name = "text_place", gp = gpar(col = "red")) 

script <- ' 
var txt = null; 
function f() { 
    var id = this.id.match(/geom_point2.([0-9]+)\\.points.*\\.([0-9]+)$/); 
    txt.textContent = label[id[1]-1][id[2]-1]; 
} 

window.addEventListener("load",function(){ 
    var es = document.getElementsByTagName("circle"); 
    for (i=0; i<es.length; ++i) es[i].addEventListener("mouseover", f, false); 

    txt = (document.getElementById("text_place").getElementsByTagName("tspan"))[0]; 

},false); 
' 

grid.script(script = script) 
grid.script(script = paste("var label = ", jlabel)) 

gridToSVG() 

¿Conoces algunos lugares donde subir archivos SVG?

+0

¡Impresionante! Sin embargo, tuve que eliminar el argumento 'filename =" s.js "' para que esto funcionara. – joran

+0

gracias. Ese es mi error – kohske

+0

¡Guau! Ese es un código serio. Muchas gracias. –

Cuestiones relacionadas