6

跟进最近的一个问题,这个问题有点不同,并使用更简单的示例更充分地说明了问题。下面是两个数据集和三个函数。第一个按预期画了一些点和一个圆圈:

library("ggplot2")
library("grid")

td1 <- data.frame(x = rnorm(10), y = rnorm(10))

tf1 <- function(df) { # works as expected
    p <- ggplot(aes(x = x, y = y), data = df)
    p <- p + geom_point(color = "red")
    p <- p + annotation_custom(circleGrob())
    print(p)
}

tf1(td1)

下一个似乎要求提供确切的示例图,但代码略有不同。它不会给出错误但不会画圆:

tf2 <- function(df) { # circle isn't draw, but no error either
    p <- ggplot()
    p <- p + geom_point(data = df, aes(x = x, y = y), color = "red")        
    p <- p + annotation_custom(circleGrob())
    print(p)
    }

tf2(td1)

最后,这个涉及更复杂的美学,并在您尝试创建圆圈时提供一个空层:

td3 <- data.frame(r = c(rnorm(5, 5, 1.5), rnorm(5, 8, 2)),
    f1 = c(rep("L", 5), rep("H", 5)), f2 = rep(c("A", "B"), 5))

tf3 <- function(df) {
    p <- ggplot()
    p <- p + geom_point(data = df, 
        aes(x = f1, y = r, color = f2, group = f2))     
#   p <- p + annotation_custom(circleGrob()) # comment out and it works
    print(p)
    }

tf3(td3)

现在,我怀疑这里的问题不是代码,而是我未能掌握 ggplot2 的内部工作原理。 我可以肯定地解释为什么在第二种情况下没有绘制圆圈以及为什么在第三种情况下图层是空的。 我查看了代码annotation_custom,它有一个硬连线inherit.aes = TRUE,我认为这是问题所在。我不明白为什么这个功能需要任何美学(参见上面的文档)。我确实尝试了几种方法来覆盖它并设置inherit.aes = FALSE,但我无法完全穿透命名空间并使其粘住。我试图以 ggplot2 创建的对象为例,但这些proto对象嵌套非常深且难以破译。

4

1 回答 1

2

要回答这个问题:

“我不明白为什么这个功能需要任何美学”。

实际上annotation_custom 需要 x 和 y aes 来缩放它的 grob,并在native单位之后使用。基本上它是这样做的:

  x_rng <- range(df$x, na.rm = TRUE)                            ## ranges of x :aes x
  y_rng <- range(df$y, na.rm = TRUE)                            ## ranges of y :aes y
  vp <- viewport(x = mean(x_rng), y = mean(y_rng),              ##  create a viewport
                 width = diff(x_rng), height = diff(y_rng),
                 just = c("center","center"))
  dd <- editGrob(grod =circleGrob(), vp = vp)                  ##plot the grob in this vp 

为了说明这一点,我在一个虚拟绘图中添加了一个 grob,用作我的 grob 的比例。一是规模大,二是规模小。

base.big   <- ggplot(aes(x = x1, y = y1), data = data.frame(x1=1:100,y1=1:100))
base.small <- ggplot(aes(x = x1, y = y1), data = data.frame(x1=1:20,y1=1:1))

我定义了我的 grob,请参阅我使用 xmin、xmax、ymin、ymax 的原生比例

annot <- annotation_custom(grob = circleGrob(),  xmin = 0, 
                                                 xmax = 20, 
                                                 ymin = 0, 
                                                 ymax = 1)

现在查看 ( ) 和 ( )之间的尺度差异(小点/大圆圈)。base.big +annotbase.small + annot

library(gridExtra)
grid.arrange(base.big+annot,
             base.small+annot)

在此处输入图像描述

于 2013-01-19T15:09:31.547 回答