ggplot2的奇怪行为

时间:2016-08-20 18:00:18

标签: r ggplot2

我只想使用ggplot2在散点图上绘制多个箭头。在这个(虚拟)示例中,绘制了一个箭头,但它随着i的增加而移动,并且只绘制了一个箭头。为什么会这样?

library(ggplot2)
a <- ggplot(mtcars, aes(wt, mpg)) + geom_point()
b <- data.frame(x1=c(2,3),y1=c(10,10),x2=c(3,4),y2=c(15,15))
for (i in 1:nrow(b)) {
        a <- a + geom_segment(arrow=arrow(), 
          mapping = aes(x=b[i,1],y=b[i,2],xend=b[i,3],yend=b[i,4]))
         plot(a)
 }

感谢。

2 个答案:

答案 0 :(得分:3)

这不是奇怪的行为,这正是aes()应该起作用的方式。它延迟了参数的评估,直到绘图实际运行。如果将表达式包含在data.frame(如i)和函数(如[,])之外的变量中,则会出现问题。当你真正“画出”情节时,这些只会被评估。

如果您想强制评估参数,可以使用aes_。这对你有用

for (i in 1:nrow(b)) {
  a <- a + geom_segment(arrow=arrow(), 
    mapping = aes_(x=b[i,1],y=b[i,2],xend=b[i,3],yend=b[i,4]))
 }
plot(a)

现在在循环内,x=y=等参数在环境中进行评估,其值在图层中“冻结”。

当然,最好不要在循环中构建图层,而只是按照@ eipi10的答案指出一个正确的数据对象。

答案 1 :(得分:2)

正如@Roland在评论主题中解释的那样,只绘制了一个箭头,因为geom_segment(arrow=arrow(), mapping = aes(x=b[i,1],y=b[i,2],xend=b[i,3],yend=b[i,4]))仅在绘制a时进行评估。但i每次a绘制时只有一个值。在第一次循环中i=1和第二次i=2期间。循环i之后仍然等于2.因此,每次只绘制一个箭头。如果在循环之后运行i=1:2,那么您将获得两个箭头。另一方面,如果您将i更改为1和/或2以外的任何内容,则无法绘制任何箭头。

在任何情况下,您都可以获得两个没有循环的箭头,如下所示:

ggplot(mtcars, aes(wt, mpg)) + 
  geom_point() +
  geom_segment(data=b, arrow=arrow(), aes(x=x1,y=y1,xend=x2,yend=y2))

关于@Roland的第一条评论的问题:通过添加新的geom_segment,每次循环时都不应更新对象a吗?例如,如果我从OP的原始a开始,那么在循环的一次迭代之后,

a = a + geom_segment(arrow=arrow(), aes(x=b[1,1],y=b[1,2],xend=b[1,3],yend=b[1,4])) 

然后,在循环的两次迭代之后,

a = a + geom_segment(arrow=arrow(), aes(x=b[1,1],y=b[1,2],xend=b[1,3],yend=b[1,4])) + 
        geom_segment(arrow=arrow(), aes(x=b[2,1],y=b[2,2],xend=b[2,3],yend=b[2,4])) 

在每种情况下a表示循环开始前a的值。无论何时或是否评估a,都不应发生对象a的基础更改?