简体   繁体   English

ggplot2 0.9.3中美学的继承和annotation_custom的行为

[英]inheritance of aesthetics in ggplot2 0.9.3 & the behavior of annotation_custom

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)

Now, I suspect the problem here is not the code but my failure to grasp the inner workings of ggplot2. 现在,我怀疑这里的问题不是代码,而是我无法掌握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. 我查看了annotation_custom的代码,它有一个硬连线的inherit.aes = TRUE ,我认为是问题所在。 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. 我尝试了几种方法来覆盖它并设置inherit.aes = FALSE但我无法完全穿透命名空间并使其坚持下去。 I tried to example the objects created by ggplot2 but these proto objects are nested very deeply and hard to decipher. 我试图举例说明ggplot2创建的对象,但这些proto对象嵌套得非常深,难以破译。

To answer this : 要回答这个问题:

"I don't see why this function needs any aesthetic at all". “我不明白为什么这个功能需要任何美学”。

In fact annotation_custom need x and y aes to scale its grob, and to use after the native units. 事实上, annotation_custom需要x和y来缩放它的grob,并在本native单元之后使用。 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 

To illustrate this I add a grob to a dummy plot used as a scale for my grob. 为了说明这一点,我将一个grob添加到一个虚拟图中,用作我的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))

I define my grob, see I use the native scales for xmin,xmax,ymin,ymax 我定义了我的grob,看我使用xmin,xmax,ymin,ymax的原生比例

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

Now see the scales difference( small point / big circle ) between ( base.big +annot ) and ( base.small + annot ). 现在看看( base.big +annot )和( base.small + annot )之间的比例差异( 小点 / 大圆圈 )。

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

在此输入图像描述

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM