在 ggplot2 中跨多个图创建线

Create line across multiple plots in ggplot2

我想结合 patchwork 包创建一条横跨两个地块的水平线。

library(ggplot2)
library(patchwork)

# Annotation after plot
p1 <- ggplot(mtcars, aes(x=disp,y=mpg))+
  geom_point()
p2 <- ggplot(mtcars, aes(x=hp,y=mpg))+
  geom_point()
# Want line across plots at y (mpg) of 15
p3 <- (p1+p2)+annotate("segment",x=-Inf,xend=Inf,y=15,yend=15)
p3

此方法仅将线穿过最后一个图 (p2)。

尝试在每个图上添加注释。

# Annotation with each plot
p1 <- ggplot(mtcars, aes(x=disp,y=mpg))+
  geom_point()+
  annotate("segment",x=-Inf,xend=Inf,y=15,yend=15)
p2 <- ggplot(mtcars, aes(x=hp,y=mpg))+
  geom_point()+
  annotate("segment",x=-Inf,xend=Inf,y=15,yend=15)

p1+p2

此方法将线放在每个图上,但不在图之间。

我想要这样的东西:

您可以使用 grid.draw 绘制线条,该线条绘制在绘图 window:

中的任何其他内容之上
library(grid)
p3
grid.draw(linesGrob(x = unit(c(0.06, 0.98), "npc"), y = unit(c(0.277, 0.277), "npc")))

但是,这里有一些注意事项。线条的确切定位由您决定,尽管如果这是您要经常做的事情,定位可以通过编程方式完成,但一次性调整 x 和 y 值以获得线条会更快在你想要的地方,就像我在不到一分钟的时间里所做的那样。

第二个注意事项是该行位于 npc space 中,而 ggplot 使用固定间距和灵活间距的组合。这样做的结果是,无论何时调整绘图大小时,线都会相对于绘图移动。同样,这可以通过编程方式修复。如果你真的想打开那罐蠕虫,你可以在我对

的回答中看到一个类似点的解决方案

我喜欢@Allan 的回答,但这是使用 facet_wrap.

的替代方法

首先,我们需要将数据旋转更长的时间,以使其处于可以使用的形式 facet_wrap。然后黑客开始。首先,我们需要使用 strip.position = 'bottom' 将小平面条标签移动到下方。然后我们可以使用 coord_cartesian(clip = 'off') 关闭裁剪,以便可以在图形区域之外绘制线条。接下来我们修复 xlim 以便当您尝试在图形区域外绘制线段时图形绘制区域不会改变。

最后,大黑客,你用新数据绘制 geom_segment,这样它只在一个方面绘制。您在调用 geom_segment 中创建了一个新的 data.frame,其中包含的数据使其在最后一个要呈现的面板中绘制,因此该行位于顶部。

最后,只是 theme() 中的一些更改,因此条带背景为空白,并且放置在轴刻度之外。

library(ggplot2)
library(dplyr)
library(tidyr)
ggplot(pivot_longer(mtcars, -mpg) %>% filter(name %in% c("disp", "hp")),
       aes(x=value, y=mpg, group=name)) +
  geom_point() + 
  facet_wrap(.~name, strip.position = "bottom") + 
  geom_segment(data = data.frame(mpg = 15, name = "hp"),
               x=-650, xend=525, y=15, yend=15) +
  coord_cartesian(clip = 'off', xlim = c(0,500)) +
  theme(aspect.ratio = 1,
        strip.background = element_blank(),
        strip.placement = "outside") +
  labs(x = "")