2012-01-23 26 views
8

Cho một ggplot, ví dụ, điểm, làm thế nào bạn sẽ tìm ra hàng dữ liệu mà một điểm cho trước tương ứng với?Làm thế nào để bạn liên kết ggplot2 grobs trở lại dữ liệu?

Một ô tiêu chuẩn:

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

Chúng tôi có thể nhận được grobs có chứa điểm với 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) 

biến mới nhất này có chứa thông tin chi tiết của các tọa độ x-y, và pointsize, vv (thử unclass(point_grobs[[1]])), nhưng nó không phải là rõ ràng như thế nào tôi nhận được hàng dữ liệu trong mtcars rằng mỗi điểm tương ứng với.


Để trả lời câu hỏi của kohske về lý do tại sao tôi làm điều này, tôi đang sử dụng gridSVG để tạo một phân tán tương tác. Khi bạn cuộn chuột qua một điểm, tôi muốn hiển thị thông tin theo ngữ cảnh. Trong ví dụ mtcars, tôi có thể hiển thị chú giải công cụ với tên của ô tô hoặc các giá trị khác từ hàng đó của khung dữ liệu.

ý tưởng hacky tôi cho đến nay là bao gồm một cột id như một nhãn văn bản vô hình:

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

Sau đó đi qua cây của grobs từ grob trỏ đến grob văn bản, và hiển thị các dãy số liệu được lập chỉ mục theo nhãn.

Điều này khó sử dụng và không phải là rất chung chung. Nếu có cách để lưu trữ giá trị id trong grob điểm, nó sẽ sạch hơn nhiều.

+0

Không có cách nào dễ dàng. Mục tiêu cuối cùng của bạn là gì? Có thể có lựa chọn thay thế. – kohske

+0

@kohske: Quá dài để nhận xét, vì vậy tôi đã cập nhật câu hỏi để giải thích những gì tôi đang làm. –

+0

Rất thú vị. Tôi hiểu mục đích của bạn. Thật không may, chúng tôi không có cách nào để truy cập dữ liệu thông qua grob (ngay cả trong bản phát hành tiếp theo, có thể). Nhưng có lẽ sẽ hữu ích khi có thông tin về dữ liệu (đặc biệt là khi 'stat =" identity "). Tôi sẽ thảo luận. – kohske

Trả lời

7

Tập lệnh này tạo tệp SVG trong đó bạn có thể chú thích tương tác các điểm.

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

Bạn có biết một số nơi tôi có thể tải lên tệp SVG không?

+0

Tuyệt vời! Tuy nhiên, tôi đã phải loại bỏ đối số 'filename =" s.js "' để làm việc này cho tôi. – joran

+0

cảm ơn. Đó là sai lầm của tôi. – kohske

+0

Wow! Đó là một số mã nghiêm trọng. Cảm ơn nhiều. –

Các vấn đề liên quan