Как управлять макетом сюжета с помощью фиксированных позиций? - PullRequest
26 голосов
/ 19 марта 2011

Я пытаюсь нарисовать сетевую визуализацию, чтобы она напоминала блок-схему. Я довольно близок со следующим кодом, но у меня есть пара вопросов:

  1. Это лучший алгоритм layout (), или я могу вручную назначить позицию для каждого узла>
  2. Как я могу убедиться, что эти узлы не перекрываются на графике (как они делают здесь)?
  3. Могу ли я назначить один узел в качестве "якоря" или отправной точки? то есть я могу сделать "C" самым верхним или самым левым узлом?

Большое спасибо !!

library("igraph")
L3 <- LETTERS[1:8]
d <- data.frame(start = sample(L3, 16, replace = T), end = sample(L3, 16, replace = T),
                weight = c(20,40,20,30,50,60,20,30,20,40,20,30,50,60,20,30))


g <- graph.data.frame(d, directed = T)

V(g)$name 
E(g)$weight

ideg <- degree(g, mode = "in", loops = F)

col=rainbow(12) # For edge colors

plot.igraph(g, 
  vertex.label = V(g)$name, vertex.label.color = "gray20",
  vertex.size = ideg*25 + 40, vertex.size2 = 30,
  vertex.color = "gray90", vertex.frame.color = "gray20",
  vertex.shape = "rectangle",
  edge.arrow.size=0.5, edge.color=col, edge.width = E(g)$weight / 10,
  edge.curved = T, 
  layout = layout.reingold.tilford)

Ответы [ 2 ]

36 голосов
/ 19 марта 2011

Расположение в igraph определяется в виде матрицы с 2 столбцами и строкой для каждого узла.В первом столбце указывается его позиция x, а во втором - позиция y, а масштаб не имеет значения (он всегда масштабируется, чтобы соответствовать области построения от -1 до 1. Вы можете получить этот макет перед построением, просто вызвав функцию макета на графике.:

 l <-layout.reingold.tilford(g) 
 l
     [,1] [,2]
[1,]    0    0
[2,]   -1    3
[3,]    0    1
[4,]    0    3
[5,]    0    2
[6,]    0    4
[7,]    1    3

Таким образом, вы можете изменить его любым способом, который хотите вручную, а затем отправить его на график:

plot.igraph(g, 
  vertex.label = V(g)$name, vertex.label.color = "gray20",
  vertex.size = ideg*25 + 40, vertex.size2 = 30,
  vertex.color = "gray90", vertex.frame.color = "gray20",
  vertex.shape = "rectangle",
  edge.arrow.size=0.5, edge.color=col, edge.width = E(g)$weight / 10,
  edge.curved = T, 
  layout = l)

Также кажется, что вы можете установить аргумент params для управления макетом abit. Это список, содержащий аргумент root, который, очевидно, можно использовать для установки корня графа. Присвойте ему номер узла (помните, что igraph сначала использует C-подобные индексы для узлов, сначалаодин равен 0). Поэтому установка корня в «C»:

l <- layout.reingold.tilford(g,params=list(root=2))

РЕДАКТИРОВАТЬ: Кроме того, RGraphViz имеет несколько хороших макетов дерева, которые, возможно, стоит проверить.


РЕДАКТИРОВАТЬ 2:

Это модифицированный фрагмент исходных кодов из моего пакета, в котором используется матрица компоновки того же типа для определения размещения узлов в графе, что может оказаться полезным:

gridLayout <- function(x)
{
    LmatX <- seq(-1,1,length=ncol(x))
    LmatY <- seq(1,-1,length=nrow(x))

    loc <- t(sapply(1:max(x),function(y)which(x==y,arr.ind=T)))
    layout <- cbind(LmatX[loc[,2]],LmatY[loc[,1]])
    return(layout)
}

Эта функция выполняет преобразование матрицы, задающей макет в сетке (аналогично layout()), в макет из двух столбцов с позициями x и y.Определите матрицу нулей и для каждого узла целое число от 1 до общего числа узлов (это идентификатор igraph + 1).

Например, для глупого графа из 4 узлов:

grid <- matrix(c(
    0,0,1,0,0,
    2,0,3,0,4),nrow=2,byrow=TRUE)

library("igraph")

g <- graph.adjacency(matrix(1,4,4))

plot(g,layout=gridLayout(L))
6 голосов
/ 24 января 2017

Менее сложный метод, чем приведенный выше, если вы хотите назначить местоположения узлов самостоятельно, это добавить столбцы с метками x и y в таблицу данных с координатами x и y для соответствующих узлов в этих столбцах.например,

library('igraph')
nodes <- c('a','b','c','d')
x <- c(0,1,2,3)
y <- c(0,1,2,3)
from <- c('a','b','c')
to <- c('b','c','d')
NodeList <- data.frame(nodes, x ,y)
EdgeList <- data.frame(from, to)
a<- graph_from_data_frame(vertices = NodeList, d= EdgeList, directed = FALSE)
plot(a)

enter image description here

...