Создание кругового / концентрического двудольного графа в r - PullRequest
1 голос
/ 29 мая 2019

решено: см. Мое решение, добавлено внизу поста.

В настоящее время я пытаюсь создать круговой двудольный граф, используя 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()

...