Рисование сети в 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 цветами. Получайте удовольствие от этого. Существуют эвристики, поиск планарного графика, а также форсированное направление и чтение планарных графов...