叠加子图 ggraph

Overlaying subplot ggraph

我需要在 ggraph 上叠加一组子图。每个地块都对应一个特定的节点,因此必须使用每个节点的坐标 放置它们 。以下代码创建图形和要叠加的子图集。

 # Create the graph
 library(data.table)
 library(igraph)
 library(ggraph)

 mydata <- data.table(from=c("John", "John", "Jim"), to=c("John", "Jim", "Jack"))
 graph <- graph_from_data_frame(mydata)
 V(graph)$class <- c("John", "Jim", "Jack")

 ggraph(graph, layout = 'linear') + 
 geom_edge_link() + 
 geom_node_point() +
 geom_node_text(aes(label = class))

 # Plots to overlay
 John <- ggplot(diamonds, aes(carat)) + geom_histogram(fill = "red") + 
 ggtitle("John")
 Jim <- ggplot(diamonds, aes(depth)) + geom_histogram(fill = "blue") + 
 ggtitle("Jim")
 Jack <- ggplot(diamonds, aes(price)) + geom_histogram(fill = "green") + 
 ggtitle("Jack")

下图说明了实际和期望的结果。

您可以使用 ggraph::create_layout 提取节点的 x 和 y 坐标,然后使用 purrr::pmapggplot2::annotation_custom 应用于每个子图。

library(purrr)
library(ggplot2)
library(igraph)
library(ggraph)

# Your code, mostly unchanged (removed data.table)
mydata <- data.frame(from=c("John", "John", "Jim"), to=c("John", "Jim", "Jack"))
graph <- graph_from_data_frame(mydata)
V(graph)$class <- c("John", "Jim", "Jack")


John <- ggplot(diamonds, aes(carat)) + geom_histogram(fill = "red") + 
  ggtitle("John")
Jim <- ggplot(diamonds, aes(depth)) + geom_histogram(fill = "blue") + 
  ggtitle("Jim")
Jack <- ggplot(diamonds, aes(price)) + geom_histogram(fill = "green") + 
  ggtitle("Jack")

# New code
graph_df <- create_layout(graph, layout = 'linear')

graph_df 是一个包含以下内容的数据框:

  x y name class ggraph.orig_index circular ggraph.index
1 1 0 John  John                 1    FALSE            1
2 2 0  Jim   Jim                 2    FALSE            2
3 3 0 Jack  Jack                 3    FALSE            3

可以直接调用ggraph(graph_df);在引擎盖下 ggraph(graph) 正在执行相同的步骤。


现在我们制作一个嵌套列表,其中第一个元素是我们要用于插图的 ggplot 对象的列表(确保它们的顺序正确,相对于它们在 graph_df 中的顺序) ).第二个元素是 x 坐标列表,第三个元素是 y 坐标列表。然后我们应用一个构造 grobs 的函数来插入,使用 x 和 y 坐标定义一个框,它将在最终图中进入。

grobs <- pmap(.l = list(plots = list(John, Jim, Jack), 
                        x = as.list(graph_df$x), 
                        y = as.list(graph_df$y)),

              .f = function(plots, x, y) {

    annotation_custom(grob = ggplotGrob(plots + theme_grey(base_size = 4)),
                      xmin = x - .25, xmax = x + .25,
                      ymin = y + .1,  ymax = y + .6)
  })

那么你上面的代码只需要添加这个对象并调整一些限制:

ggraph(graph_df) + 
  geom_edge_link() + 
  geom_node_point() +
  geom_node_text(aes(label = class)) + 
  expand_limits(x = c(0.5,3.5)) +
  coord_equal() +
  grobs

一些注意事项:

  • 插图的构造也可以使用 purrr 函数以编程方式完成。
  • 我们创建的函数中的 base_size = 参数需要根据您的喜好进行调整。
  • 函数中 x 和 y 的偏移也必须根据实际绘图中的坐标范围手动完成。