如何在R中使用ggplot连接两个不同地图的点?

4

我有两个数据框 df1df2,如下所示:

> df1
  dateTime value
1        1     6
2        2     2
3        3     3
4        4     1

> df2
  dateTime value
1        1     3
2        2     8
3        3     4
4        4     5

我想在一个图表中绘制这些数据帧,在同一x轴上将它们分成两个不同的图表,并将df1的每个值连接到相应的df2值。实际上,这是我想要的图表:

output

我写的代码试图得到上面的图表,代码如下:
library(grid)
library(dplyr)

plot1 <- df1 %>%
  select(dateTime, value) %>%
  na.omit() %>%
  ggplot() +
  geom_point(data = df1, aes(dateTime, value)) +
  geom_line(data = df1, aes(x = dateTime, y = value), color = 'green') +
  geom_segment(data = setNames(cbind(df1, df2), c("x1", "y1", "x2", "y2")),
                aes(x = x1, y = y1, xend = x2, yend = y2), linetype = "dashed") +
  theme(axis.text=element_text(size = 14), axis.title=element_text(size = 14),
        axis.title.x=element_blank(),
        axis.text.x=element_blank(),
        axis.ticks.x=element_blank())

plot2 <- df2 %>%
  select(dateTime, value) %>%
  na.omit() %>%
  ggplot() +
  geom_point(data = df2, aes(dateTime, value)) + 
  geom_line(data = df2, aes(x = dateTime, y = value), color = 'red') +
  geom_segment(data = setNames(cbind(df1, df2), c("x1", "y1", "x2", "y2")),
                aes(x = x1, y = y1, xend = x2, yend = y2), linetype = "dashed") +
  xlab("dateTime") +
  theme(axis.text=element_text(size = 14), axis.title=element_text(size = 14))

grid.newpage()
grid.draw(rbind(ggplotGrob(plot1), ggplotGrob(plot2), size = "last"))

但结果是:

output2


4
相关链接:https://dev59.com/W47ea4cB1Zd3GeqPAFx7 - MrFlick
相关链接:https://stackoverflow.com/questions/50685081/draw-a-line-across-multiple-ggplot-figures-in-a-gtable-matrix - user10191355
1个回答

2

我有一个使用gtable的微妙解决方案来解决您的问题。首先,我们将制作类似于您制作的图形。我改变的是在ggplot()调用中指定公共映射。接下来,在geom_segment()中,我分别将yend设置为-InfInf以在图形段中进行绘制。


plot1 <- df1 %>%
  select(dateTime, value) %>%
  na.omit() %>%
  ggplot(aes(dateTime, value)) +
  geom_point() +
  geom_line(color = "green") +
  geom_segment(aes(xend = dateTime, yend = -Inf), linetype = "dashed") +
  theme(axis.text=element_text(size = 14), axis.title=element_text(size = 14),
        axis.title.x=element_blank(),
        axis.text.x=element_blank(),
        axis.ticks.x=element_blank())

plot2 <- df2 %>%
  select(dateTime, value) %>%
  na.omit() %>%
  ggplot(aes(dateTime, value)) +
  geom_point() +
  geom_line(color = "red") +
  geom_segment(aes(xend = dateTime, yend = Inf), linetype = "dashed") +
  xlab("dateTime") +
  theme(axis.text=element_text(size = 14), axis.title=element_text(size = 14))

在这一步,我们将组合的grobs转换为gtable:

library(gtable)
gt <- rbind(ggplotGrob(plot1), ggplotGrob(plot2), size = "last")

从这个gtable中,我们查找需要在绘图面板之间放置额外图形对象的值。我建议不要盲目相信你的面板grobs在gt$grobs[[6]]中,而且线段不在gt$grobs[[6]]$children[[5]]中。自己查看数据结构,并确认这些元素在你的gtable中的位置。最初的回答。
# Panel positioning
is_panel <- which(gt$layout$name == "panel")
panel_x <- unique(gt$layout$l[is_panel])
panel_y <- gt$layout$t[is_panel]

# Coordinates and graphical parameters for segments
x_coords <- gt$grobs[[is_panel[1]]]$children[[5]]$x0
gpar <- gt$grobs[[is_panel[1]]]$children[[5]]$gp

现在,我们将创建一个新的grob,模拟段的x位置但跨越整个视口。我们将把它添加到gtable中。最初的回答中提到了这一步骤。
linkgrob <- segmentsGrob(x0 = x_coords, y0 = 0, x1 = x_coords, y1 = 1, gp = gpar)
gt <- gtable_add_grob(gt, linkgrob,
                      t = panel_y[1] + 1, l = panel_x, b = panel_y[2] - 1)
grid.newpage()
grid.draw(gt)

在我的手中,这产生了以下的情节:

这是图片的描述

最初的回答。

使用 Inf-Inf 有点棘手,但我仍然找不到其他解决方案。 - Patris

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接