2012-01-23 12 views
8

उदाहरण के लिए, अंक के एक ggplot को देखते हुए, आप डेटा की पंक्ति कैसे प्राप्त करेंगे जो किसी दिए गए बिंदु से मेल खाता है?आप ggplot2 grobs को डेटा पर वापस कैसे जोड़ते हैं?

एक नमूना साजिश:

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

हम grobs कि 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) 

यह पिछले चर x-y निर्देशांक का विवरण, और pointsize, आदि (unclass(point_grobs[[1]]) कोशिश) शामिल हैं, लेकिन यह स्पष्ट नहीं है कि कैसे मैं mtcars में डेटा की पंक्ति है कि प्रत्येक बिंदु से मेल खाती है मिलता है।


कारण है कि मैं यह कर रहा हूं, मैं एक इंटरैक्टिव scatterplot बनाने के लिए gridSVG उपयोग कर रहा हूँ के बारे में kohske के सवाल का जवाब करने के लिए। जब आप माउस को एक बिंदु पर रोल करते हैं, तो मैं प्रासंगिक जानकारी प्रदर्शित करना चाहता हूं। Mtcars उदाहरण में, मैं डेटा फ्रेम के उस पंक्ति से कार या अन्य मानों के नाम के साथ टूलटिप दिखा सकता हूं।

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

तब पाठ Grob इंगित Grob से grobs के वृक्ष पार, और डाटासेट की पंक्ति प्रदर्शित:

मेरे hacky विचार अब तक एक अदृश्य पाठ लेबल के रूप में एक id कॉलम शामिल करने के लिए है लेबल द्वारा अनुक्रमित।

यह बेहद सामान्य और बहुत सामान्य नहीं है। यदि बिंदु grob के भीतर id मान को स्टोर करने का कोई तरीका है, तो यह बहुत साफ होगा।

+0

कोई आसान तरीका नहीं है। आपका अंतिम लक्ष्य क्या है? विकल्प हो सकते हैं। – kohske

+0

@ कोहस्के: एक टिप्पणी के लिए बहुत लंबा, इसलिए मैंने यह प्रश्न समझाया कि मैं क्या कर रहा हूं। –

+0

बहुत दिलचस्प है। मैं आपका उद्देश्य समझता हूं। दुर्भाग्य से हमारे पास ग्रोब के माध्यम से डेटा तक पहुंचने का कोई तरीका नहीं है (यहां तक ​​कि अगली रिलीज में भी, शायद)। लेकिन शायद डेटा के बारे में जानकारी रखना उपयोगी होगा (विशेष रूप से जब 'stat = "पहचान")। में चर्चा करूंगा। – kohske

उत्तर

7

यह स्क्रिप्ट एक एसवीजी फ़ाइल उत्पन्न करती है जिसमें आप बिंदुओं को अंतःक्रियात्मक रूप से एनोटेट कर सकते हैं।

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

क्या आप कुछ स्थानों को जानते हैं जो मैं एसवीजी फ़ाइल अपलोड कर सकता हूं?

+0

बहुत बढ़िया! हालांकि, मुझे यह मेरे लिए काम करने के लिए 'filename = "s.js"' तर्क को हटाना पड़ा था। – joran

+0

धन्यवाद। यह मेरी गलती है। – kohske

+0

वाह! यह कुछ गंभीर कोड है। बहुत धन्यवाद। –

संबंधित मुद्दे