9

我想弄清楚如何在 ggplot 中使用 grconvertX/grconvertX。我的最终目标是通过从用户坐标到设备坐标来为ggplot2图形(可能还有lattice 添加注释。我知道它可以用 grobs 完成,但我想知道是否有更简单的方法。grid.textgrid.lines

以下代码允许我将值从用户坐标传递到 ndc 坐标,并使用这些值用grid.text.

graphics.off()      # close graphics windows   

library(grid)
library(gridBase)


test= data.frame(
  x = c(1,2,3),
  y = c(12,10,3),
  n = c(75,76,73)
  )

par(mar = c(13,5,2,3))

plot(test$y ~ test$x,type="b", ann=F)

for (i in 1:nrow(test))

{
  X=grconvertX(i , from="user", to="ndc")
  grid.text(x=X, y =0.2, label=paste("GRID.text at\nuser.x=", i, "\n", "ndc.x=", (signif( X, 5))   ) ) 
  grid.lines(x=c(X, X), y = c(0.28, 0.33) )
}
#add some code to save as PDF ...

在此处输入图像描述

该代码基于我之前的一篇文章中的解决方案:混合 X 和 Y 坐标系。您可以看到原始绘图中的 x 坐标是如何转换为 ndc 的。这种方法的优点是我可以为 Y 使用设备坐标。

我以为我可以在ggplot2(也可能在lattice)中轻松地做同样的事情。

library(ggplot2)
graphics.off()      # close graphics windows   

qplot(x=x, y=y, data=test)+geom_line()+  opts(plot.margin = unit(c(1,3,8,1), "lines"))

for (i in 1:nrow(test))

{
  X=grconvertX(i , from="user", to="ndc")
  grid.text(x=X, y =0.2, label=paste("GRID.text at\nuser.x=", i, "\n", "ndc.x=", (signif( X, 5))   ) ) 
  grid.lines(x=c(X, X), y = c(0.28, 0.33) )
}

#add some code to save as PDF...

但是,它不能正常工作。坐标好像有点不对。垂直线和文本与图上的刻度标签不对应。谁能告诉我如何解决它?提前非常感谢。

在此处输入图像描述

4

1 回答 1

12

grconvertXand函数使用grconvertY基本图形,而 ggplot2 使用网格图形。一般来说,这两种不同的图形引擎不能很好地协同工作(尽管您已经演示了使用gridBaseto help)。您的第一个示例有效,因为您从基本图形开始,因此用户坐标系与基本图形一起存在并grconvertX从中转换。在第二种情况下,用户坐标系从未在基本图形中设置,因此看起来它可能使用默认坐标 0,1,这与顶部视口坐标相似但不完全相同,因此您会得到类似但不完全正确的东西(我真的很惊讶你没有收到错误或警告

通常对于网格图形,在坐标之间进行转换的等价物是仅使用感兴趣的坐标系创建一个新的视口(或使用正确的坐标系推送/弹出到现有视口),然后在该视口中添加注释。

这是一个创建绘图的示例,然后向下移动到包含主绘图的视口,创建一个具有相同尺寸但关闭裁剪的新视口,x 比例基于数据,y 比例为 0,1 ,然后相应地添加一些文本:

library(ggplot2)
library(grid)

test= data.frame(   x = c(1,2,3),   y = c(12,10,3),   n = c(75,76,73)   )  

qplot(x=x, y=y, data=test)+geom_line()+  opts(plot.margin = unit(c(1,3,8,1), "lines"))  

current.vpTree()
downViewport('panel-3-4')
pushViewport(dataViewport( test$x, clip='off',yscale=c(0,1)))

for (i in 1:nrow(test))  {
    grid.text(x=i, y = -0.2, default.units='native',
        label=paste("GRID.text at\nuser.x=", i, "\n"   ) )
        grid.lines(x=c(i, i), y = c(-0.1, 0), default.units='native' )
 } 

这里棘手的事情之一是 ggplot2 没有设置视口比例以匹配正在绘制的数据,而是自己进行转换。在这种情况下,根据 x 数据设置比例是可行的,但如果 ggplot2 做了一些更有趣的事情,那么这可能不起作用。我们需要的是某种方法来从 ggplot2 获取转换后的坐标,以便在对 grid.text 的调用中使用。

于 2012-05-10T17:36:54.263 回答