ggplot2 0.9.3及更高版本中美学的继承comment_custom的行为 [英] inheritance of aesthetics in ggplot2 0.9.3 & the behavior of annotation_custom
问题描述
紧随最近的问题 mine ,这个问题有点不同,并使用更简单的示例更全面地说明了该问题.以下是两个数据集和三个功能.第一个按预期绘制了一些点和一个圆:
Following up on a recent question of mine, this one is a bit different and illustrates the problem more fully using simpler examples. Below are two data sets and three functions. The first one draws some points and a circle as expected:
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)
下一个似乎要求提供确切的样图,但代码略有不同.它不会给出错误,但不会画出圆圈:
This next one seems to ask for the exact sample plot but the code is slightly different. It does not give an error but does not draw the circle:
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)
最后,这涉及一种更复杂的美学,并在您尝试创建圆时提供了一个空白层:
Finally, this one involves a more complex aesthetic and gives an empty layer when you try to create the circle:
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
对象嵌套得非常深,难以破解.
Now, I suspect the problem here is not the code but my failure to grasp the inner workings of ggplot2. I could sure use an explanation of why the circle is not drawn in the 2nd case and why the layer is empty in the third case. I looked at the code for annotation_custom
and it has a hard-wired inherit.aes = TRUE
which I think is the problem. I don't see why this function needs any aesthetic at all (see the docs on it). I did try several ways to override it and set inherit.aes = FALSE
but I was unable to fully penetrate the namespace and make it stick. I tried to example the objects created by ggplot2 but these proto
objects are nested very deeply and hard to decipher.
推荐答案
要回答这个问题:
我不明白为什么该功能根本不需要任何美感."
"I don't see why this function needs any aesthetic at all".
实际上,annotation_custom
需要x和y aes来缩放其grob,并在native
个单位之后使用.
基本上是这样做的:
In fact annotation_custom
need x and y aes to scale its grob, and to use after the native
units.
Basically it did this :
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的比例.第一个是大规模,第二个是小规模.
To illustrate this I add a grob to a dummy plot used as a scale for my grob. The first is a big scale and the second is a small one.
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的本机刻度
I define my grob, see I use the native scales for xmin,xmax,ymin,ymax
annot <- annotation_custom(grob = circleGrob(), xmin = 0,
xmax = 20,
ymin = 0,
ymax = 1)
现在可以看到(base.big +annot
)和(base.small + annot
)之间的比例差异(小点/大圆圈).
Now see the scales difference(small point / big circle) between (base.big +annot
) and (base.small + annot
).
library(gridExtra)
grid.arrange(base.big+annot,
base.small+annot)
这篇关于ggplot2 0.9.3及更高版本中美学的继承comment_custom的行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!