Визуализация статических и динамических сетей на R, часть 6 +7


В первой части:

  • визуализация сетей: зачем? каким образом?
  • параметры визуализации
  • best practices — эстетика и производительность
  • форматы данных и подготовка
  • описание наборов данных, которые используются в примерах
  • начало работы с igraph

Во второй части: цвета и шрифты в графиках R.

В третьей части: параметры графов, вершин и ребер.

В четвертой части: размещения сети.

В пятой части: акцентирование свойств сети, вершин, ребер, путей.

В этой части: интерактивная визуализация сетей, другие способы представления сети.

Интерактивное построение графиков с tkplot


R и igraph позволяют интерактивно строить графики сетей. Это может быть полезно, если нужно слегка изменить вид небольшого графа. После ручной настройки можно получить координаты вершин и использовать их для других построений.
tkid <- tkplot(net) # tkid - идентификатор tkplot, который откроется
l <- tkplot.getcoords(tkid) # получаем координаты из tkplot
plot(net, layout=l)



Другие способы представления сети


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

Например, вот тепловая карта матрицы сети:
netm <- get.adjacency(net, attr="weight", sparse=F)
colnames(netm) <- V(net)$media
rownames(netm) <- V(net)$media

palf <- colorRampPalette(c("gold", "dark orange")) 
heatmap(netm[,17:1], Rowv = NA, Colv = NA, col = palf(100), 
        scale="none", margins=c(10,10) )



В зависимости от того, какие свойства сети, ее вершин или ребер наиболее важны, простые графики могут оказаться более информативными, чем карта сети.
dd <- degree.distribution(net, cumulative=T, mode="all")
plot(dd, pch=19, cex=1, col="orange", xlab="Degree", ylab="Cumulative Frequency")



Построение парных сетей с igraph


У парных, или двудольных, графов встречаются два разных вида узлов и связей, но не в каждом. Наш второй пример со средствами массовой информации — именно такая сеть, в ней исследуются связи между источниками новостей и их потребителями. Как будет показано ниже, на этот раз ребра сети заданы в матричном виде. Их можно считать в объект-граф, используя graph.incidence. В igraph двудольные сети имеют параметр ребра type, равный 0 для одной группы вершин и 1 для другой.
head(nodes2)
head(links2)

net2 <- graph.incidence(links2)
table(E(net2)$type)

plot(net2, vertex.label=NA)



Как и с однодольными сетями, можно изменить объект-сеть, чтобы он включал визуальные свойства, используемые по умолчанию при построении. Обратите внимание, в этот раз мы также изменим форму вершин — средства массовой информации будут квадратиками, а их потребители — кружочками.
V(net2)$color <- c("steel blue", "orange")[V(net2)$type+1]
V(net2)$shape <- c("square", "circle")[V(net2)$type+1]
V(net2)$label <- ""
V(net2)$label[V(net2)$type==F] <- nodes2$media[V(net2)$type==F] 
V(net2)$label.cex=.4
V(net2)$label.font=2

plot(net2, vertex.label.color="white", vertex.size=(2-V(net2)$type)*8) 



У igraph также есть специальное представление для двудольных сетей (хотя оно не всегда хорошо подходит, возможно, лучшим решением будет создать собственное двудольное представление).
plot(net2, vertex.label=NA, vertex.size=7, layout=layout.bipartite) 



Иногда может быть полезно использовать текстовые метки в качестве вершин:
plot(net2, vertex.shape="none", vertex.label=nodes2$media,
     vertex.label.color=V(net2)$color, vertex.label.font=2, 
     vertex.label.cex=.6, edge.color="gray70",  edge.width=2)



В этом примере мы также поэкспериментируем с использованием картинок в качестве вершин. Для этого понадобится библиотека png (если она не установлена, воспользуйтесь install.packages("png")).
# install.packages("png")
library(png)
 
img.1 <- readPNG("./images/news.png")
img.2 <- readPNG("./images/user.png")

V(net2)$raster <- list(img.1, img.2)[V(net2)$type+1]

plot(net2, vertex.shape="raster", vertex.label=NA,
     vertex.size=16, vertex.size2=16, edge.width=2)



Кстати, на график тоже можно добавить любую картинку. Например, очень многие графы сетей можно сильно улучшить, добавив фото щенка, который несет корзинку с котятами.
l <- layout.auto(net2, ymin=-1.5, ymax=1.5, xmin=-1.5, xmax=1.5)

plot(net2, vertex.shape="raster", vertex.label=NA,
     vertex.size=16, vertex.size2=16, edge.width=2, layout=l)

img.3 <- readPNG("./images/puppy.png")
rasterImage(img.3,  xleft=-1.7, xright=0, ybottom=-1.2, ytop=0)



# Числа после картинки - ее координаты
# Границы построения заданы в par()$usr

Хорошая практика — отключать пакеты, когда они больше не нужны. Постарайтесь это запомнить, потому что пакеты из набора igraph и statnet порождают ошибки, если их загрузить вместе.
detach(package:png) 
detach(package:igraph)


Небольшой пример с использованием пакета network


Построение с пакетом network очень похоже на igraph, хотя синтаксис и отличается немного (полный набор новых названий параметров!). Этот пакет также использует меньше настроек по умолчанию, полученных изменением объекта-сети, и более явные параметры в функции построения.

Вот небольшой пример с использованием (уже знакомой) сети со средствами массовой информации. Начнем с конвертирования данных в формат network, который используется семейством пакетов Statnet (в том числе network, sna, ergm, stergm и других).

Как и в igraph, можно создать объект 'network' из списка ребер, матрицы сопряжения или связности. Подробности можно узнать, выполнив ?edgeset.constructors. Как и в примере с igraph, будем использовать список ребер и блоки данных с атрибутами вершин, чтобы создать объект-сеть. Одна особенность, на которую стоит обратить внимание — параметр ignore.eval. По умолчанию он установлен в TRUE, и эта настройка указывает объекту-сети игнорировать веса ребер.
library(network)

net3 <- network(links,  vertex.attr=nodes, matrix.type="edgelist", 
                loops=F, multiple=F, ignore.eval = F)

Здесь так же легко получить доступ к вершинам, ребрам и матрице сети:
net3[,]
net3 %n% "net.name" <- "Media Network" #  параметр сети
net3 %v% "media"    # параметр вершины
net3 %e% "type"     # параметр вершины

Давайте снова построим нашу сеть средств массовой информации:
net3 %v% "col" <- c("gray70", "tomato", "gold")[net3 %v% "media.type"]
plot(net3, vertex.cex=(net3 %v% "audience.size")/7, vertex.col="col")



Обратите внимание, что как и в igraph, построение возвращает координаты вершин. Их можно использовать в других графиках с помощью параметра coord.
l <- plot(net3, vertex.cex=(net3 %v% "audience.size")/7, vertex.col="col")
plot(net3, vertex.cex=(net3 %v% "audience.size")/7, vertex.col="col", coord=l)


detach(package:network)

Чтобы получить полный список параметров, доступных в пакете network, выполните ?plot.network.




К сожалению, не доступен сервер mySQL