Нарисовать сеть в R (контроль толщины ребер плюс неперекрывающиеся ребра) - PullRequest
16 голосов
/ 23 сентября 2011

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

  1. Чтобы можно было контролировать толщину каждого края.
  2. Края не должны перекрываться (т. Е. Форма ребер от A до B не рисуется поверх ребер от B до A)

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

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

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

Ответы [ 4 ]

23 голосов
/ 23 сентября 2011

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

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

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

Он содержит узел происхождения в первом столбце, узел назначения во втором и вес в третьем.Вы можете использовать мой 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]))

Обратите внимание на преобразование в матрицу и вычитание единицы, потому что первый узел равен 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

1 голос
/ 23 сентября 2011

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

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

1 голос
/ 23 сентября 2011

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

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).

1 голос
/ 23 сентября 2011

Хотя это и не R-ответ, я бы рекомендовал использовать Cytoscape для создания сети.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...