R 每组/ggplot2等效类型的线前打印点=";o";

R 每组/ggplot2等效类型的线前打印点=";o";,r,plot,ggplot2,R,Plot,Ggplot2,假设我想用点和线绘制一个图,其中点出现在每组中对应线的前面。特别是,我希望使用红色填充点打印组1,其中点通过一条线连接,但使用(仅)一条蓝线打印组2,但我希望在组1上打印组2。例如,在基本图形中: 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]

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

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))

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

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

所需顺序为(第1组线),(第1组点),(第2组线)。我可以通过再次手动覆盖几何图形来做到这一点,一次一组,但这太难看了

我认为解决这一问题的“最佳”解决方案是编写一个低级别的
geom_linepoint
,它可以根据需要工作;我已经调查了一下,它是。。。有人能提出一个更干净、更简单的解决方案吗

这里有一个“低技术”的解决方案。下面是一个函数,它为给定分组变量的每个级别依次添加一个线图层和一个点图层

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")



“低技术”与写新几何相比@巴普蒂斯特(现已删除)的答案确实创建了一个新的geom,并且似乎完成了工作,因此我不确定他为什么要删除它。

自定义geom似乎并不太难,因为您将回收现有组件并将其简单地包装在一个新容器中。另一方面,与任何ggplot2黑客一样,你可能会冒着它在未经通知的情况下崩溃的风险。我认为它会(1)比你想象的更难,(2)比你想象的更不脆弱,因为现在有一种官方描述的创建新几何图形的机制(在我的问题中链接)。我开始研究
geom_linepoint()
(这是我一直想要的东西,但我意识到
geom_path
(用于黑客攻击/扩展的合适的基本几何体)比我能快速处理的稍微复杂一些(例如,你可能是对的,我对这一点的看法与大多数人不同。我在2009年写了一些自定义几何图形,其中一个是模仿
类型='b'
,当时有一个用于附加组件的ggExtra包,写了一个wiki页面来描述过程,等等。所以我觉得很困惑,为什么所有人突然都认为这是一件值得去做的事情扩展ggplot2,并以某种方式对内部更改更具鲁棒性。这些年来,我已经看到了100多件我贡献的东西,这让我对引入定制解决方案更加厌倦和谨慎。公平地说……现在扩展似乎更“受欢迎”(并受到ggplot2开发人员的鼓吹),但这肯定不是保证。您现在删除的解决方案有什么问题?
 g0 +  geom_line() + geom_point()+ 
     geom_point(data=d1)+
     geom_line(data=d2,show.legend=FALSE)
 ggsave("order4.png",width=3,height=3)
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")