在每个组的行前面绘制点/ ggplot2相当于type =“o”

假设我想绘制一个包含点和线的图形,其中点出现在每个组中相应行的前面.特别是,我想要用红色填充点绘制组1,其中点通过线连接,但是组2用(仅)蓝线绘制,但我希望组2绘制在组1上.例如,在基本图形中:

set.seed(101)
dd <- data.frame(x=rep(1:10,2),
         y=rep(1:10,2),
                 f=factor(rep(1:2,each=10)))
dd$y[11:20] <-     dd$y[11:20] + rnorm(10)
d1 <- subset(dd,f=="1")
d2 <- subset(dd,f=="2")

par(cex=1.5)
plot(y~x,data=d1,bg="red",pch=21,type="o")
lines(y~x,data=d2,col="blue",lwd=2)
legend("bottomright",c("group 1","group 2"),
       col=c("black","blue"),
       pch=c(21,NA),
       pt.bg=c("red",NA),
       lty=1,
       lwd=c(1,2))

《在每个组的行前面绘制点/ ggplot2相当于type =“o”》

(我的真实数据有点复杂.)我想在ggplot2中干净利落地尝试一下.

如果我在线之前绘制点,则组1的点将被同一组中的线覆盖:

 library(ggplot2); theme_set(theme_bw())
 g0 <- ggplot(dd,aes(x,y,fill=f,colour=f,shape=f))+
     scale_fill_manual(values=c("red",NA))+
     scale_colour_manual(values=c("black","blue")) +
     scale_shape_manual(values=c(21,NA))
 g0 + geom_point()+  geom_line()
 ggsave("order2.png",width=3,height=3)

《在每个组的行前面绘制点/ ggplot2相当于type =“o”》

如果我在点之前绘制线条,则组2的线条将被组1的点覆盖:

 g0 + geom_line()+  geom_point()
 ggsave("order3.png",width=3,height=3)

《在每个组的行前面绘制点/ ggplot2相当于type =“o”》

期望的顺序是(组1行),(组1点),(组2行).我可以通过再次手动覆盖geoms,一次一组,但这很丑陋.

 g0 +  geom_line() + geom_point()+ 
     geom_point(data=d1)+
     geom_line(data=d2,show.legend=FALSE)
 ggsave("order4.png",width=3,height=3)

我认为对此的“最佳”解决方案是编写一个可以按需运行的低级geom_linepoint;我已经对此进行了一些调查,这是not entirely trivial …任何人都可以提出更简洁的解决方案吗?

《在每个组的行前面绘制点/ ggplot2相当于type =“o”》

最佳答案 这是一个“低技术”
1解决方案.下面是一个函数,它为给定分组变量的每个级别连续添加一个线图层,然后是一个点图层.

linepoint = function(data, group.var, lsize=1.2, psize=4) {
  lapply(split(data, data[,group.var]), function(dg) {
    list(geom_line(data=dg, size=lsize),
         geom_point(data=dg, size=psize)) 
  })
}

ggplot(dd, aes(x,y, fill=f, colour=f,shape=f))+
  scale_fill_manual(values=c("red",NA))+
  scale_colour_manual(values=c("black","blue")) +
  scale_shape_manual(values=c(21,NA)) +
  linepoint(dd, "f")

《在每个组的行前面绘制点/ ggplot2相当于type =“o”》

1“低技术”与编写新的geom相比. @ baptiste(现已删除)的答案确实创建了一个新的geom,似乎完成了工作,所以我不确定他为什么要删除它.

点赞