跟进我最近的一个问题,这个问题有点不同,并使用更简单的示例更充分地说明了问题。下面是两个数据集和三个函数。第一个按预期画了一些点和一个圆圈:
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
对象嵌套非常深且难以破译。