решено: см. Мое решение, добавлено внизу поста.
В настоящее время я пытаюсь создать круговой двудольный граф, используя r, в идеале - ggraph.У меня есть набор данных о взаимоотношениях между мужской и женской лягушками;Вот подмножество этих данных:
Mother Father
M1 F1
M2 F2
M3 F2
M4 F3
M5 F4
M6 F4
M7 F4
, и моя цель состоит в том, чтобы визуализировать количество партнеров, которые есть у каждого организма, примерно так:
концентрический двудольный график, показывающий отношениямежду отцовскими и отцовскими организмами
До сих пор я был в состоянии сделать линейную версию графика, используя igraph:
> library(tidyverse)
> library(igraph)
> library(ggraph)
> MyData <- read_csv("Bipartite.csv")
> Visualization <-graph.data.frame(MyData)
> bipartite.mapping(Visualization)
$res
[1] TRUE
$type
[1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
TRUE TRUE TRUE
[14] TRUE TRUE TRUE TRUE TRUE TRUE TRUE
> V(Visualization)$type <- bipartite_mapping(Visualization)$type
> plot(Visualization, layout = layout.bipartite)
, который производит это: Линейныйдвудольный график, показывающий отношения между матерями и отцами;очень запутанный и трудно читаемый, так как этикетки перекрываются
Я застрял при преобразовании этого в круговую визуализациюЯ попробовал две вещи:
Во-первых, поместив объект igraph в ggraph и нанеся его с помощью схемы «круг»:
> ggraph(Visualization, layout = 'circle')
+ geom_edge_link()
+ geom_node_point()
Но вместо двух концентрических колец япросто получите один большой круг, который бесполезен для отображения данных (и я мог бы сделать это проще, просто используя ggraph, я знаю).
Визуализация данных спаривания в одном кольце, когда матери и отцы находятся в одном кольце
Во-вторых, я попытался перенести объект igraph в ggraph и установить циркулярTRUE:
ggraph(Visualization, layout = 'bipartite', circular = TRUE)
+ geom_edge_link()
+ geom_node_point()
Но я получаю сообщение об ошибке:
Error in layout_igraph_igraph(graph, layout, circular, ...) :
Circular layout only applicable to tree and DAG layout
Есть мысли о том, как создать визуализацию, которую я ищу?Я очень новичок в r и stackoverflow, поэтому я прошу прощения за любые ограничения в объяснении моей проблемы.Спасибо!
РЕШЕНИЕ:
Сначала загрузите нужные вам пакеты.
library(tidyverse)
library(tidygraph)
library(igraph)
library(ggraph)
Теперь прочитайте данные вашего узла и ребра и создайте объект графа с помощью ggraph.
Nodes <- read_csv("Nodes.csv")
Edges <- read_csv("Edges.csv")
Graph <- tbl_graph(nodes = Nodes, edges = Edges)
Затем создайте объект, представляющий ваш график с двудольным макетом.
g <- Graph
V(g)$type <- bipartite_mapping(g)$type
На основе этого объекта двудольного графа мы найдем координаты x и y для каждого узла, которые размещают узлы в концентрические окружности.Во-первых, используйте create_layout, чтобы создать объект, "координаты", который описывает текущий двухсторонний макет.ordinates содержит столбцы для координат x и y каждого узла в линейном двудольном графе.
coords <- create_layout(g, layout = "bipartite") %>%
Далее, мы будем использовать некоторые триггеры для изменения координат x и y по сравнению с координатамилинейный двудольный граф с координатами x и y, которые описывают круговой граф.Сначала выберите столбцы x и y.
select(x, y) %>%
Эта строка создает столбец "тэта", который в основном делит единичный круг на кусочки в зависимости от количества узлов, которые нам нужно разместить вдоль края круга,и назначает срез каждому узлу.
mutate(theta = x / (max(x) + 1) * 2 * pi,
В следующих строках создаются значения r, радиусы окружностей, на которые будут помещены узлы, и находим координаты x и y на декартовой плоскости, которая будет размещать каждый узелпо краю кругов.
r = y + 1,
x = r * cos(theta),
y = r * sin(theta))
Теперь мы создаем совершенно новый макет графика, который дает позиции узлов на основе тех круговых координат, которые мы только что создали в координатах.
my_graph <- create_layout(g, "manual", node.position = coords)
Я также хочу убедиться, что метки для каждого узла повернуты логически, чтобы не было перекрытия меток и чтобы все метки легко читались.Для этого сначала создайте объект с именем «label_data» на основе «координаты».
label_data <- coords
Добавьте новый столбец для label_data с именем «angle», преобразовав тэта-столбец.от радианов до градусов.
label_data$angle <- (label_data$theta)*(180/pi)
Если бы мы просто использовали это значение угла, то метки в третьем и четвертом квадрантах круга были бы вверх ногами.Таким образом, мы преобразуем значения углов в этих областях, чтобы перевернуть их правой стороной вверх.
label_data$plottingangle<-ifelse(label_data$angle < 270 & label_data$angle > 90, label_data$angle - 180, label_data$angle)
Наконец, мы просто строим графический объект, который имеет созданный нами макет, определяя угол поворота для меток в эстетике geom_node_text.Тада!
ggraph(my_graph) + geom_edge_link(edge_colour = "gray73") + geom_node_point(size = 0.8) + geom_node_text(aes(label = IndividualID, angle = label_data$plottingangle), size = 3) + scale_shape_manual(values = c(0, 19)) + coord_fixed() + theme_graph()