2015-03-05 4 views
1

У меня есть график с < 100 узлов, с несколькими категориями. Я хотел бы, чтобы узлы, принадлежащие одной категории, были в центре, а остальные узлы располагались равномерно по кругу вокруг - как звездный график, но с несколькими узлами в центре. NodeXL называет это полярный график (см: http://www.connectedaction.net/2013/03/03/how-to-plot-a-network-in-a-polar-layout-using-nodexl/) Учитывая эти данные из руководства для графов из dataframes:Как создать полярный график сети (несколько колец) в igraph & R

actors<-data.frame(name=c("Alice", "Bob", "Cecil", "David", 
         "Esmeralda"), 
       age=c(48,33,45,34,21), 
       gender=c("F","M","F","M","F")) 
relations <- data.frame(from=c("Bob", "Cecil", "Cecil", "David", 
          "David", "Esmeralda"), 
        to=c("Alice", "Bob", "Alice", "Alice", "Bob", "Alice"), 
        same.dept=c(FALSE,FALSE,TRUE,FALSE,FALSE,TRUE), 
        friendship=c(4,5,5,2,1,1), advice=c(4,5,5,4,2,3)) 
g <- graph.data.frame(relations, directed=TRUE, vertices=actors) 

Что делать, если я хочу, чтобы женщины в центре и самцов, расположенных по кругу вокруг? Я могу разделить график и график каждого отдельно, но у меня возникли проблемы с размышлением о том, как их собрать вместе, и я ищу еще один ответ.

gsubf<-induced.subgraph(g,V(g)$gender=="F") 
gsubm<-induced.subgraph(g,V(g)$gender=="M") 
gsubfcoords<-layout.fruchterman.reingold(gsubf, xlim=c(-2,2), ylim=c(-2,2)) 
gsubmcoords<-layout.circle(gsubm) 

Тогда я мог бы отнести их к V (gsubf) $ х, V (gsubf) $ у ..., но я изо всех сил, как поставить все это вместе. Может быть, есть более простой способ? или, может быть, другой пакет, чтобы сделать полярный?

ответ

3

Я недавно ответил на этот вопрос в списке рассылки, но для полноты я также включу здесь ответ.

igraph layouts - это просто матрицы с двумя столбцами и одной строкой для каждой вершины, , поэтому проще всего, если вы сами создаете такую ​​матрицу. Если вы хотите поместить вершину в радиусе от центра с углом альфа (в радианах), то вы должны использовать следующие формулы, чтобы выяснить X и Y координату:

X = r * cos(alpha) 
Y = -r * sin(alpha) 

где координата Y сбрасывается только потому, что ось Y координаты система экрана ориентирована сверху вниз. Таким образом, вы можете создать такую ​​функцию в R:

polar.layout <- function(radii, angles) { 
    cbind(radii*cos(angles), -radii*sin(angles))   
} 

polar.layout функция должна быть вызвана с двумя списками: один, который определяет радиус каждой вершины и один, который определяет угол наклона каждой вершины. Это будет возвращать матрицу объект, который может быть передан в plot() следующим образом:

layout <- polar.layout(radii, angles) 
plot(graph, layout=layout) 

Так все, что вам нужно, это два вектора: один для радиусов и один для углов. Вы можете построить их из полов следующим образом:

males <- which(V(g)$gender == "M") 
females <- which(V(g)$gender == "F") 
radii <- ifelse(V(g)$gender == "F", 1, 2) 
angles <- rep.int(0, vcount(g)) 
angles[males] <- (1:length(males)-1) * 2 * pi/length(males) 
angles[females] <- (1:length(females)-1) * 2 * pi/length(females) 
layout <- polar.layout(radii, angles) 
plot(g, layout=layout) 
+0

Извините, я до сих пор не видел ваш список рассылки. Спасибо! Это должно сработать. – ChristinaP

Смежные вопросы