Как вы соотносите гробы ggplot2 с данными? - PullRequest
8 голосов
/ 23 января 2012

Учитывая ggplot, например, точек, как вы узнаете строку данных, которой соответствует данная точка?

Пример графика:

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

Мы можемполучить значения, содержащие точки с 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)

Эта последняя переменная содержит сведения о координатах xy, размере точек и т. д. (попробуйте unclass(point_grobs[[1]])), но это не так.Понятно, как я получаю строку данных в mtcars, которой соответствует каждая точка.


Чтобы ответить на вопрос Кохске о том, почему я это делаю, я использую gridSVG для создания интерактивногорассеивания.Когда вы наводите курсор мыши на точку, я хочу отобразить контекстную информацию.В примере с mtcars я мог бы показать всплывающую подсказку с именем автомобиля или другими значениями из этой строки фрейма данных.

Пока что моя хакерская идея - включить столбец id в качестве невидимого текста.label:

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

Затем обведите дерево гробов от точечного гроба до текстового гроба и отобразите строку набора данных, проиндексированную меткой.

Это довольно неудобно и не оченьобобщать.Если есть способ сохранить значение id в пределах точки, это будет намного чище.

1 Ответ

7 голосов
/ 23 января 2012

Этот скрипт генерирует SVG-файл, в котором вы можете интерактивно комментировать точки.

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

Знаете ли вы, где я могу загрузить файл SVG?

...