Наложение субплота 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")
Следующее изображение иллюстрирует фактический и желаемый результат.
1 ответ
Ты можешь использовать ggraph::create_layout
чтобы извлечь координаты х и у узлов, а затем использовать purrr::pmap
применять ggplot2::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 в функции также должны быть выполнены вручную, исходя из диапазона координат в вашем реальном графике.