Как изменить масштаб графика, чтобы раздвинуть кластеры (узлы) немного дальше друг от друга и назвать кластеры в igraph?

У меня есть информация об узлах и ребрах, и я пытаюсь сделать с ней сетевой график. Информация об узлах содержит 1552 строки с информацией:

А информация о краях представлена ​​четырьмя столбцами с 1203576 записями.

Используя данные узлов и ребер, я использовал приведенный ниже код для построения сетевого графика.

library(igraph)
net <- graph_from_data_frame(d=edges, vertices=nodes, directed=F)

plot(net, edge.arrow.size=.4,vertex.label=NA, 
     vertex.color=as.numeric(factor(nodes$type)))

Grouped.net = net
E(Grouped.net)$weight = 1

colnames(nodes)[4] <- "Clusters"

## Add edges with high weight between all nodes in the same group
for(Clus in unique(nodes$Clusters)) {
  GroupV = which(nodes$Clusters == Clus)
  Grouped.net = add_edges(Grouped.net, combn(GroupV, 2), attr=list(weight=500))
} 


## Now create a layout based on G_Grouped
set.seed(567)
LO = layout_with_fr(Grouped.net)

# Generate colors based on media type:
colrs <- c("gray50", "yellow", "tomato")
V(net)$color <- colrs[V(net)$type_num]


plot(net, layout=LO, edge.arrow.size=0,vertex.label=NA, asp=0, vertex.size=4)
legend(x=-1.5, y=-1.1, c("typeA","typeB", "typeC"), pch=21,
       col="#777777", pt.bg=colrs, pt.cex=2, cex=.8, bty="n", ncol=1)

Сюжет, который я получил, выглядит следующим образом:

введите здесь описание изображения

На приведенном выше рисунке есть 5 кластеров.

  1. Как увеличить расстояние между кластерами? Как их далеко передвинуть? И как настроить края? Они выглядят странно.

  2. Как назвать кластеры на рисунке?

  3. Как вывести узлы типа C в топ? Их очень мало. Так как тип A огромен по количеству, то тип C был ниже.

Любая помощь приветствуется. спасибо


person beginner    schedule 29.09.2020    source источник
comment
Сайт, на котором вы разместили свои данные, требует установки новых драйверов для Windows. Я этого делать не буду и другим не советую. Можете ли вы найти способ предоставить свои данные, который не требует, чтобы я модифицировал свою машину?   -  person G5W    schedule 29.09.2020
comment
@ G5W Я также сохранил данные в Dropbox и делюсь здесь https://www.dropbox.com/sh/w10weg5k9qh1zq4/AABHY9XxA0ap_cxxi3q01C7Ea?dl=0 Пожалуйста, дайте мне знать, можете ли вы их загрузить или нет.   -  person beginner    schedule 29.09.2020
comment
Мне удалось получить версию для дропбокса. Благодарю. Это может занять некоторое время, но я постараюсь ответить   -  person G5W    schedule 29.09.2020
comment
@G5W Конечно, спасибо   -  person beginner    schedule 29.09.2020


Ответы (1)


У вас есть несколько вопросов. Я постараюсь ответить на них все, но в другом порядке.

Настройка

library(igraph)
edges = read.csv("temp/edges_info_5Clusters.csv", stringsAsFactors=T)
nodes = read.csv("temp/nodes_info_5Clusters.csv", stringsAsFactors=T)

Вопрос 3. Как вывести узлы типа C наверх?
Узлы отображаются в порядке их номеров. Чтобы отобразить нечастые типы, нам нужно, чтобы эти узлы получили самые высокие номера узлов. Поэтому просто отсортируйте типы, чтобы узлы были в порядке TypeA, TypeB, TypeC.

nodes = nodes[order(nodes$type),]
net <- graph_from_data_frame(d=edges, vertices=nodes, directed=F)

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

Grouped.net = net
E(Grouped.net)$weight = 1
colnames(nodes)[4] <- "Clusters"

## Add edges with high weight between all nodes in the same group
for(Clus in unique(nodes$Clusters)) {
  GroupV = which(nodes$Clusters == Clus)
  Grouped.net = add_edges(Grouped.net, combn(GroupV, 2), attr=list(weight=500))
} 

## Now create a layout based on G_Grouped
set.seed(567)
LO = layout_with_fr(Grouped.net)

colrs <- c("gray50", "yellow", "tomato")
V(net)$color <- colrs[V(net)$type_num]

plot(net, layout=LO, edge.arrow.size=0,vertex.label=NA, vertex.size=4,
    edge.color="lightgray")
legend(x=-1.5, y=-1.1, c("typeA","typeB", "typeC"), pch=21,
       col="#777777", pt.bg=colrs, pt.cex=2, cex=.8, bty="n", ncol=1)

Сетевой график — версия 1

Хорошо, теперь TypeC и TypeB гораздо лучше видны, но пять кластеров расположены плохо. Чтобы получить что-то более похожее на ваш второй (пример) график, нам нужно построить макет иерархически: сначала расположить кластеры, а затем отдельно расположить точки внутри кластеров. Схема для пяти кластеров проста.

F5 = make_full_graph(5)
Stretch = 6
LO_F5 = Stretch*layout.circle(F5)
plot(F5, layout=LO_F5)
 

Макет для кластеров

Теперь нам нужно расположить точки в каждом кластере и разнести их, используя только что созданный макет кластера. Но здесь есть компромисс. Если вы сделаете кластеры далеко друг от друга, все узлы будут маленькими и их будет трудно увидеть. Если вы хотите, чтобы узлы были больше, вам нужно сделать кластер ближе друг к другу (чтобы все они поместились на графике). У вас так много ссылок, что независимо от того, что вы делаете, все ссылки будут сливаться вместе, как серый фон. Я выбрал золотую середину, которая мне понравилась, но предлагаю вам изучить различные значения фактора Stretch. Большие значения Stretch сделают кластеры более отдаленными друг от друга с меньшими узлами. Меньшие значения сблизят кластеры с более крупными узлами. Выберите то, что работает для вас.

set.seed(1234)
HierLO = matrix(0, ncol=2, nrow=vcount(net))
for(i in 1:length(levels(nodes$Clusters))) {
    CLUST = which(nodes$Clusters == levels(nodes$Clusters)[i])
    SubNet = induced_subgraph(net, V(net)[CLUST])
    LO_SN = scale(layout_nicely(SubNet))
    HierLO[CLUST, ] = LO_SN + 
        matrix(LO_F5[i,], nrow=vcount(SubNet), ncol=2,byrow=TRUE)
}

plot(net, layout=HierLO, edge.arrow.size=0,vertex.label=NA, vertex.size=4,
    edge.color="lightgray")

Сетевой график — версия 2

Теперь вы можете видеть все узлы TypeC и большую часть узлов TypeB (кроме кластера 1, где много узлов TypeB).

Наконец, давайте добавим метки кластера. Их просто нужно разместить относительно центров кластеров. Эти центры своего рода задаются макетом LO_F5, но построение графика igraph изменяет масштаб макета так, что график фактически имеет диапазон (-1,1). Мы можем сами изменить масштаб LO_F5, а затем немного растянуть позиции, чтобы метки оказались сразу за пределами круга.

LO_Text = LO_F5
LO_Text[,1] = 2*(LO_F5[,1] - min(LO_F5[,1]))/(max(LO_F5[,1]) - min(LO_F5[,1])) -1
LO_Text[,2] = 2*(LO_F5[,2] - min(LO_F5[,2]))/(max(LO_F5[,2]) - min(LO_F5[,2])) -1
text(1.2*LO_Text, labels=levels(nodes$Clusters))
legend(x=-1.5, y=-1.1, c("typeA","typeB", "typeC"), pch=21,
       col="#777777", pt.bg=colrs, pt.cex=2, cex=.8, bty="n", ncol=1)

Сетевой график — версия 3

С ссылками все еще проблема, но я думаю, что это решает другие ваши вопросы.

person G5W    schedule 29.09.2020
comment
Превосходно. Большое спасибо за ответ. Это очень полезно. Да, сейчас проблема только в связях между кластерами. Я посмотрю на это. Спасибо еще раз. - person beginner; 30.09.2020