你如何将ggplot2 grobs与数据联系起来? [英] How do you relate ggplot2 grobs back to the data?

查看:96
本文介绍了你如何将ggplot2 grobs与数据联系起来?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

给定一个ggplot,例如points,你如何找出给定点对应的数据行?



一个示例图: (ggplot2)
(p < - ggplot(mtcars,aes(mpg,wt))+


  b 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坐标和pointsize等(尝试 unclass(point_grobs [[1]])),但是我不明白如何获取<$ $中的数据行c $ c> mtcars ,每个点对应。






回答kohske的问题我在做这个,我使用 gridS VG 来创建交互式散点图。当您将鼠标移到某个点上时,我想要显示上下文信息。在mtcars示例中,我可以显示一个工具提示,其中包含汽车的名称或来自该行数据框的其他值。



到目前为止,我的黑客主意是包含 id 列作为不可见的文字标签:

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

然后遍历grob树从grob到文本grob,并显示由标签索引的数据集的行。



这是很琐碎而且不太普遍。如果有一种方法可以在grob中存储 id 值,它将更加干净。



  library(ggplot2)这个脚本生成一个SVG文件,您可以在其中交互式地注释这些点。 
library(gridSVG)

geom_point2< - 函数(...)GeomPoint2 $ new(...)
GeomPoint2< - proto(GeomPoint,{
objname< - point2
draw< - 函数(。,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(color,alpha),fill = fill,label = label ,
fontsize = 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 (grep(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;
函数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文件的地方吗?


Given a ggplot of, for example, points, how would you find out the row of data that a given point corresponded to?

A sample plot:

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

We can get the grobs that contain points with 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)

This last variable contains details of the x-y coordinates, and pointsize, etc. (try unclass(point_grobs[[1]])), but it isn't obvious how I get the row of data in mtcars that each point corresponds to.


To answer kohske's question about why am I doing this, I'm using gridSVG to create an interactive scatterplot. When you roll the mouse over a point, I want to display contextual information. In the mtcars example, I could show a tooltip with the name of the car or other values from that row of the data frame.

My hacky idea so far is to include an id column as an invisible text label:

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

Then traverse the tree of grobs from the point grob to the text grob, and display the row of the dataset indexed by the label.

This is fiddly and not very generalisable. If there's a way to store the id value within the point grob, it would be much cleaner.

解决方案

This script generate a SVG file wherein you can interactively annotate the points.

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

Do you know some places I can upload SVG file?

这篇关于你如何将ggplot2 grobs与数据联系起来?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆