Me gustaría etiquetar puntos en un ggplot de forma interactiva, de modo que el mouse sobre un punto muestre una etiqueta.Etiquetas de puntos interactivos con gridSVG y ggplot2 v.0.9.0
Estoy tratando de adaptar la respuesta dada en this question para que funcione en la última versión de ggplot2. Influenciado por los comentarios en el grupo ggplot google, here, utilicé la última versión de geom-point-.r como una plantilla, agregando un campo "etiqueta" al argumento gp en varios lugares. Luego copié el código restante de la respuesta de Kohske. Pero no funciona, no hay etiquetas en el svg resultante, y no puedo entender por qué.
Me di cuenta de que todo en point_grobs_labels
es nulo, y cuando miro grid.get(point_grob_names[1])$gp
, no hay campo de etiqueta ...
library(ggplot2)
library(gridSVG)
library(proto)
library(rjson)
geom_point2 <- function (mapping = NULL, data = NULL, stat = "identity",
position = "identity",
na.rm = FALSE, ...) {
ggplot2:::GeomPoint$new(mapping = mapping, data = data, stat = stat,
position = position,
na.rm = na.rm, ...)
}
GeomPoint2 <- proto(ggplot2:::Geom, {
objname <- "point"
draw_groups <- function(., ...) .$draw(...)
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())
with(coord_transform(coordinates, data, scales),
ggname(.$my_name(), pointsGrob(x, y, size=unit(size, "mm"), pch=shape,
gp=gpar(
col=alpha(colour, alpha),
fill = alpha(fill, alpha),
label = label,
fontsize = size * .pt)))
)
}
draw_legend <- function(., data, ...) {
data <- aesdefaults(data, .$default_aes(), list(...))
with(data,
pointsGrob(0.5, 0.5, size=unit(size, "mm"), pch=shape,
gp=gpar(
col = alpha(colour, alpha),
fill = alpha(fill, alpha),
label = label,
fontsize = size * .pt)
)
)
}
default_stat <- function(.) StatIdentity
required_aes <- c("x", "y")
default_aes <- function(.) aes(shape=16, colour="black", size=2,
fill = NA, alpha = NA, label = NA)
})
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)
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()
Nice! ¡Gracias! Estaba buscando un ejemplo completo y funcional como este. Sin embargo, tengo un par de preguntas: ¿qué papel juega "proto" en el guión? Lo estás usando para redefinir geom_point, ¿verdad? Estoy interesado en crear gráficos interactivos de gráficos ggplot2 que hice. ¿Puede recomendar algún tutorial/fuente para que R trabaje con Javascript con RJSON y cree SVG? – MatteoS
@MatteoS, Desafortunadamente, no puedo ayudarlo mucho aquí, principalmente intenté encontrar una solución a este problema en particular. Pero puede que tenga razón, posiblemente la redefinición de 'geom_point' nos permita usar estas etiquetas, que yo llamaría la base al menos en este caso. Por lo tanto, le ofrecería explorar este ejemplo, especialmente Javascript, las partes 'grid.get()' y 'grid.ls()'. – Julius
Ok, gracias por su ayuda. ¡Aquí está tu bien merecida recompensa! – MatteoS