简体   繁体   English

如何使用R中的ggplot将两个不同图的点相互连接?

[英]How to connect points of two different plots to each other using ggplot in R?

I have two dataframes df1 and df2 as follows: 我有两个数据帧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

I want to plot these dataframes in just one diagram, split them to two different plots with same x axis, and connect each value of df1 to the corresponding value of df2 . 我想在一个图中绘制这些数据帧,将它们分成两个具有相同x轴的不同图,并将每个df1值连接到相应的df2值。 Actually, here is the diagram which I want: 实际上,这是我想要的图表:

产量

The code which I wrote to try to get the above diagram is: 我为了获得上面的图而编写的代码是:

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

But the result is: 但结果是:

OUTPUT2

I have a slightly hacky solution to your problem using gtable. 我使用gtable对你的问题有一个轻微的hacky解决方案。 First, we'll make the plots similar to how you made them. 首先,我们将制作类似于您制作它们的图形。 The thing I've changed is to specify common mappings inside the ggplot() call. 我改变的是在ggplot()调用中指定公共映射。 Next, in geom_segment() I've set the yend to -Inf and Inf in the segments for the plots respectively. 接下来,在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))

At this point we convert the combined grobs to a gtable: 此时我们将组合的grob转换为gtable:

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

From this gtable, we look up the values that we need to place an extra graphical object in between the plotting panels. 从这个gtable中,我们查找在绘图面板之间放置一个额外图形对象所需的值。 I'd recommend not blindly trusting that your panel grobs are in gt$grobs[[6]] and that the segments arent in gt$grobs[[6]]$children[[5]] . 我建议不要盲目相信你的面板凹凸处于gt$grobs[[6]]并且这些段gt$grobs[[6]]$children[[5]] Look through the data structure yourself and confirm where these elements are in your gtable. 自己查看数据结构并确认这些元素在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

Now, we're going to make a new grob that mimicks the x-positions of the segments but span the entire viewport. 现在,我们将创建一个新的grob,模仿段的x位置,但跨越整个视口。 We'll add this to the gtable. 我们将此添加到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)

And in my hands, that yielded the following plot: 在我手中,产生了以下情节:

在此输入图像描述

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM