Рисование сети в R (толщина контрольного края плюс неперекрывающиеся края)

Мне нужно нарисовать сеть с 5 узлами и 20 направленными ребрами (ребро, соединяющее каждые 2 узла) с помощью R, но мне нужны две функции:

  • Уметь контролировать толщину каждого ребра.
  • Края не должны перекрываться (т.е. форма ребра от A до B не нарисована над ребром от B до A)

Я потратил часы на поиск решения и попробовал много пакетов, но всегда есть проблема.

Может ли кто-нибудь предложить решение, пожалуйста, и представить полный пример?

Большое спасибо заранее.

Ответы

Ответ 1

Если это нормально, чтобы линии были изогнуты, я знаю два пути. Сначала создаю edgelist:

Edges <- data.frame(
    from = rep(1:5,each=5),
    to = rep(1:5,times=5),
    thickness = abs(rnorm(25)))

Edges <- subset(Edges,from!=to)

Это содержит начало node в первом столбце, node пункта назначения на втором и вес третьего. Вы можете использовать мой pacake qgraph для построения взвешенного графика, используя это. По умолчанию ребра изогнуты, если между двумя узлами есть несколько ребер:

library("qgraph")
qgraph(Edges,esize=5,gray=TRUE)

qgraph

Однако этот пакет на самом деле не предназначен для этой цели, и вы не можете изменить цвета краев (но, работая над ним:)). Вы можете сделать все края черными с небольшим трюком:

qgraph(Edges,esize=5,gray=TRUE,minimum=0,cut=.Machine$double.xmin)

Для большего контроля вы можете использовать пакет igraph. Сначала сделаем график:

library("igraph")
g <- graph.edgelist(as.matrix(Edges[,-3]))

Обратите внимание на преобразование в матрицу и вычитание одного из них, поскольку первый node равен 0. Далее мы определяем макет:

l <- layout.fruchterman.reingold(g)

Теперь мы можем изменить некоторые параметры края с помощью функции E():

# Define edge widths:
E(g)$width <- Edges$thickness * 5

# Define arrow widths:
E(g)$arrow.width <- Edges$thickness * 5

# Make edges curved:
E(g)$curved <- 0.2

И, наконец, построим график:

plot(g,layout=l)

igraph

Ответ 2

В то время, когда я не отвечал R, я бы рекомендовал использовать Cytoscape для генерации сети.

Вы можете автоматизировать его с помощью RCytoscape. http://bioconductor.org/packages/release/bioc/html/RCytoscape.html

Ответ 3

Пакет, информативно называемый "сеть", может довольно хорошо рисовать направленные сети и обрабатывать ваши проблемы.

ex.net <- rbind(c(0, 1, 1, 1), c(1, 0, 0, 1), c(0, 0, 0, 1), c(1, 0, 1, 0))

plot(network(ex.net), usecurve = T, edge.curve = 0.00001,
     edge.lwd = c(4, rep(1, 7)))

Аргумент edge.curve, если он установлен очень низко и в сочетании с usecurve = T, разделяет ребра, хотя может быть и более прямой способ сделать это, и edge.lwd может принимать вектор в качестве аргумента для разных размеров.

Это не всегда самый красивый результат, признаюсь я. Но довольно легко получить приличные сетевые графики, которые можно настроить несколькими способами (см. "Network.plot" ).

Ответ 4

Ограничение "не перекрывающихся" на ребрах является большой проблемой здесь. Во-первых, ваша сеть должна быть "плоской", иначе это невозможно в двух измерениях (вы не можете подключить три дома к газовым, электрическим, телефонным компаниям без кроссоверов).

Я думаю, что алгоритм построения планарного графа существенно решает проблему с 4 цветами. Получайте удовольствие от этого. Существуют эвристики, поиск планарного графика, а также форсированное направление и чтение планарных графов...