I'd like to label points in a ggplot interactively, so that mousing over a point shows a label.
I'm trying to adapt the answer given in this question so that it works in the latest version of ggplot2. Influenced by comments on the ggplot google group, here, I used the latest version of geom-point-.r as a template, adding a "label" field to the gp argument in various places. Then I copied the remaining code from kohske's answer. But it doesn't work -- there aren't any labels in the resulting svg, and I can't figure out why.
I did notice that everything in point_grobs_labels
is null, and when I look at grid.get(point_grob_names[1])$gp
, there is no label field...
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()