我只想使用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)
}
感谢。
答案 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
的基础更改?