前情回顧:
讀李霞老師《生物信息學(xué)》教材
Gephi網(wǎng)絡(luò)圖極簡教程
Network在單細(xì)胞轉(zhuǎn)錄組數(shù)據(jù)分析中的應(yīng)用
網(wǎng)絡(luò)數(shù)據(jù)統(tǒng)計(jì)分析筆記|| 為什么研究網(wǎng)絡(luò)
網(wǎng)絡(luò)數(shù)據(jù)統(tǒng)計(jì)分析筆記|| 操作網(wǎng)絡(luò)數(shù)據(jù)
網(wǎng)絡(luò)數(shù)據(jù)統(tǒng)計(jì)分析筆記|| 網(wǎng)絡(luò)數(shù)據(jù)可視化
網(wǎng)絡(luò)數(shù)據(jù)統(tǒng)計(jì)分析筆記|| 網(wǎng)絡(luò)數(shù)據(jù)的描述性分析
網(wǎng)絡(luò)數(shù)據(jù)統(tǒng)計(jì)分析筆記||網(wǎng)絡(luò)圖的數(shù)學(xué)模型
網(wǎng)絡(luò)數(shù)據(jù)統(tǒng)計(jì)分析筆記|| 網(wǎng)絡(luò)圖的統(tǒng)計(jì)模型
網(wǎng)絡(luò)數(shù)據(jù)統(tǒng)計(jì)分析筆記|| 網(wǎng)絡(luò)拓?fù)浣Y(jié)構(gòu)推斷
網(wǎng)絡(luò)數(shù)據(jù)統(tǒng)計(jì)分析筆記|| 網(wǎng)絡(luò)圖上的過程建模與預(yù)測
網(wǎng)絡(luò)數(shù)據(jù)統(tǒng)計(jì)分析筆記|| 動(dòng)態(tài)網(wǎng)絡(luò)
網(wǎng)絡(luò)數(shù)據(jù)統(tǒng)計(jì)分析筆記|| 案例1分析單細(xì)胞轉(zhuǎn)錄組數(shù)據(jù)
在R語言的世界里學(xué)習(xí)網(wǎng)絡(luò)數(shù)據(jù)分析盒粮,我們對一個(gè)網(wǎng)站不會(huì)陌生:https://kateto.net/
這里提供了大量network的應(yīng)用實(shí)例获黔,而且每年還會(huì)更新igraph的Workshop猫十,而這正是network很好的入門材料鹏倘,似乎成為網(wǎng)絡(luò)學(xué)習(xí)的必經(jīng)之路菜秦。所以夫偶,我們也不例外湾碎,把里面的流程走一遍厕宗,以擴(kuò)展我們的想象力画舌。
示例代碼和數(shù)據(jù)可以在github下載:https://github.com/kateto
network 可視化的目的
network 可視化的類型
網(wǎng)絡(luò)屬性
網(wǎng)絡(luò)布局
開始之前
- 必要的R包
install.packages("igraph")
install.packages("network")
install.packages("sna")
install.packages("ggraph")
install.packages("visNetwork")
install.packages("threejs")
install.packages("networkD3")
install.packages("ndtv")
- 下載示例數(shù)據(jù)和代碼:
git clone https://github.com/kateto/R-Network-Visualization-Workshop.git
R中顏色調(diào)用
顏色很漂亮,但更重要的是已慢,它們幫助人們區(qū)分對象的類型或?qū)傩缘募墑e曲聂。在大多數(shù)R函數(shù)中,您可以使用命名顏色佑惠、十六進(jìn)制或RGB值句葵。
plot(x=1:10, y=rep(5,10), pch=19, cex=3, col="dark red")
points(x=1:10, y=rep(6, 10), pch=19, cex=3, col="557799")
points(x=1:10, y=rep(4, 10), pch=19, cex=3, col=rgb(.25, .5, .3))
查看 R內(nèi)置了多少顏色:
length(colors()) # all colors)
[1] 657
光藍(lán)色就有:
grep("blue", colors(), value=T) # colors that have 'blue' in the name
[1] "aliceblue" "blue" "blue1"
[4] "blue2" "blue3" "blue4"
[7] "blueviolet" "cadetblue" "cadetblue1"
[10] "cadetblue2" "cadetblue3" "cadetblue4"
[13] "cornflowerblue" "darkblue" "darkslateblue"
[16] "deepskyblue" "deepskyblue1" "deepskyblue2"
[19] "deepskyblue3" "deepskyblue4" "dodgerblue"
[22] "dodgerblue1" "dodgerblue2" "dodgerblue3"
[25] "dodgerblue4" "lightblue" "lightblue1"
[28] "lightblue2" "lightblue3" "lightblue4"
[31] "lightskyblue" "lightskyblue1" "lightskyblue2"
[34] "lightskyblue3" "lightskyblue4" "lightslateblue"
[37] "lightsteelblue" "lightsteelblue1" "lightsteelblue2"
[40] "lightsteelblue3" "lightsteelblue4" "mediumblue"
[43] "mediumslateblue" "midnightblue" "navyblue"
[46] "powderblue" "royalblue" "royalblue1"
[49] "royalblue2" "royalblue3" "royalblue4"
[52] "skyblue" "skyblue1" "skyblue2"
[55] "skyblue3" "skyblue4" "slateblue"
[58] "slateblue1" "slateblue2" "slateblue3"
[61] "slateblue4" "steelblue" "steelblue1"
[64] "steelblue2" "steelblue3" "steelblue4"
顏色值互換:
rgb(10, 100, 100, maxColorValue=255)
[1] "#0A6464"
思考:如果是反過來呢厕鹃,如何轉(zhuǎn)化?
plot(x=1:5, y=rep(5,5), pch=19, cex=16, col=rgb(.25, .5, .3, alpha=.5), xlim=c(0,6))
如果我們有一個(gè)十六進(jìn)制的顏色乍丈,我們可以使用調(diào)整顏色從包grDevices設(shè)置透明度alpha剂碴。為了好玩,我們還使用par()函數(shù)將圖形背景設(shè)置為灰色轻专。我們不會(huì)在下面這樣做忆矛,但是我們可以使用par設(shè)置圖的邊距(mar=c(底部、左側(cè)请垛、頂部催训、右側(cè))),或者告訴R在使用par添加新圖之前不要清除前一個(gè)圖(new=TRUE)宗收。
par(bg="black")
col.tr <- grDevices::adjustcolor("#557799", alpha=0.7)
plot(x=1:5, y=rep(5,5), pch=19, cex=20, col=col.tr, xlim=c(0,6))
在許多情況下漫拭,我們需要一些對比色,或者一種顏色的多種深淺混稽。R提供了一些預(yù)定義的調(diào)色板函數(shù)采驻,可以為我們生成這些。例如:
色板(Palettes)
pal1 <- heat.colors(5, alpha=1) # generate 5 colors from the heat palette, opaque
pal2 <- rainbow(5, alpha=.5) # generate 5 colors from the heat palette, semi-transparent
plot(x=1:10, y=1:10, pch=19, cex=10, col=pal1)
par(new=TRUE) # tells R not to clear the first plot before adding the second one
plot(x=10:1, y=1:10, pch=19, cex=10, col=pal2)
我們也可以使用colorRampPalette生成我們自己的漸變匈勋。注意礼旅,colorRampPalette返回一個(gè)函數(shù),我們可以使用該函數(shù)從調(diào)色板中生成所需的任意顏色洽洁。
palf <- colorRampPalette(c("gray70", "dark red"))
plot(x=10:1, y=1:10, pch=19, cex=10, col=palf(10))
palf <- colorRampPalette(c(rgb(1,1,1, .2),rgb(.8,0,0, .7)), alpha=TRUE)
plot(x=10:1, y=1:10, pch=19, cex=10, col=palf(10))
找到好的顏色組合是一項(xiàng)艱巨的任務(wù)-和內(nèi)置的R調(diào)色板相當(dāng)有限痘系。值得慶幸的是,還有其他可用的軟件包:
library("RColorBrewer")
display.brewer.all()
這個(gè)包有一個(gè)主要的功能饿自,叫做brewery .pal谷丸。要使用它哑姚,您只需要選擇所需的調(diào)色板和一些顏色封拧。讓我們看看一些RColorBrewer調(diào)色板:
par(mfrow=c(1,3))
display.brewer.pal(8, "Set3")
display.brewer.pal(8, "Spectral")
display.brewer.pal(8, "Blues")
par(mfrow=c(1,2)) # plot two figures - 1 row, 2 columns
pal3 <- brewer.pal(10, "Set3")
plot(x=10:1, y=10:1, pch=19, cex=6, col=pal3)
plot(x=10:1, y=10:1, pch=19, cex=6, col=rev(pal3)) # backwards
數(shù)據(jù)格式
在本教程中推励,我們將主要使用兩個(gè)示例數(shù)據(jù)集。兩者都包含有關(guān)媒體組織的數(shù)據(jù)城豁。一種是新聞來源之間的超鏈接和提及苟穆。第二種是媒體場所和消費(fèi)者之間的聯(lián)系網(wǎng)絡(luò)。
雖然這里使用的示例數(shù)據(jù)很小唱星,但我們將生成的可視化背后的許多想法適用于中型和大型網(wǎng)絡(luò)雳旅。這也是為什么我們很少使用某些可視化屬性,比如節(jié)點(diǎn)符號(hào)的形狀:在較大的圖形映射中间聊,這些屬性是不可能區(qū)分的攒盈。事實(shí)上,在繪制非常大的網(wǎng)絡(luò)時(shí)哎榴,我們甚至可能想要隱藏網(wǎng)絡(luò)的邊緣型豁,而專注于識(shí)別和可視化節(jié)點(diǎn)的社區(qū)僵蛛。
此時(shí),您可以在R中可視化的網(wǎng)絡(luò)的大小主要受到您機(jī)器的RAM的限制迎变。但有一點(diǎn)需要強(qiáng)調(diào)的是充尉,在很多情況下,將較大的網(wǎng)絡(luò)可視化為巨大的毛團(tuán)比提供圖表來顯示圖表的主要特征更沒有幫助衣形。
清空我們的環(huán)境驼侠,并導(dǎo)入數(shù)據(jù):
rm(list = ls())
# Set the working directory to the folder containing the workshop files:
setwd("F:\\Rstudio\\network\\R-Network-Visualization-Workshop-master")
#setwd("C:/sunbelt2019")
# If you don't know the path to the folder and you're in RStudio, go to the
# "Session" menu -> "Set Working Directory" -> "To Source File Location"
library("igraph")
# Read in the data:
nodes <- read.csv("./Data files/Dataset1-Media-Example-NODES.csv", header=T, as.is=T)
links <- read.csv("./Data files/Dataset1-Media-Example-EDGES.csv", header=T, as.is=T)
head(nodes)
id media media.type type.label audience.size
1 s01 NY Times 1 Newspaper 20
2 s02 Washington Post 1 Newspaper 25
3 s03 Wall Street Journal 1 Newspaper 30
4 s04 USA Today 1 Newspaper 32
5 s05 LA Times 1 Newspaper 20
6 s06 New York Post 1 Newspaper 50
head(links)
from to type weight
1 s01 s02 hyperlink 22
2 s01 s03 hyperlink 22
3 s01 s04 hyperlink 21
4 s01 s15 mention 20
5 s02 s01 hyperlink 23
6 s02 s03 hyperlink 21
創(chuàng)建一個(gè) igraph對象
接下來,我們將把原始數(shù)據(jù)轉(zhuǎn)換為igraph網(wǎng)絡(luò)對象谆吴。為此倒源,我們將使用graph_from_data_frame()函數(shù),該函數(shù)接受兩個(gè)數(shù)據(jù)幀:d和vertices句狼。
- d 描述網(wǎng)絡(luò)的邊緣笋熬。它的前兩列是每條邊的源節(jié)點(diǎn)和目標(biāo)節(jié)點(diǎn)的id。下面的列是邊屬性(重量腻菇、類型胳螟、標(biāo)簽或其他)。
- vertices 頂點(diǎn)從一列節(jié)點(diǎn)id開始芜繁。下面的列都被解釋為節(jié)點(diǎn)屬性旺隙。
net <- graph_from_data_frame(d=links, vertices=nodes, directed=T)
# Examine the resulting object:
class(net)
[1] "igraph"
net
IGRAPH d431b72 DNW- 17 49 --
+ attr: name (v/c), media (v/c), media.type (v/n),
| type.label (v/c), audience.size (v/n), type (e/c),
| weight (e/n)
+ edges from d431b72 (vertex names):
[1] s01->s02 s01->s03 s01->s04 s01->s15 s02->s01 s02->s03
[7] s02->s09 s02->s10 s03->s01 s03->s04 s03->s05 s03->s08
[13] s03->s10 s03->s11 s03->s12 s04->s03 s04->s06 s04->s11
[19] s04->s12 s04->s17 s05->s01 s05->s02 s05->s09 s05->s15
[25] s06->s06 s06->s16 s06->s17 s07->s03 s07->s08 s07->s10
[31] s07->s14 s08->s03 s08->s07 s08->s09 s09->s10 s10->s03
+ ... omitted several edges
igraph對象的描述以四個(gè)字母開頭:
- D或U绒极,表示有向圖或無向圖
- N表示命名圖(其中節(jié)點(diǎn)具有name屬性)
- W表示加權(quán)圖(其中邊具有權(quán)重屬性)
- B表示二部圖(二模式圖)(其中節(jié)點(diǎn)有類型屬性)
(17 49)后面的兩個(gè)數(shù)字表示圖中的節(jié)點(diǎn)數(shù)和邊數(shù)骏令。描述還列出了節(jié)點(diǎn)和邊緣屬性,例如:
- (g/c) -圖形級字符屬性
- (v/c) -頂點(diǎn)級字符屬性
- (e/n) -邊緣級數(shù)值屬性
E(net) # The edges of the "net" object
+ 49/49 edges from d431b72 (vertex names):
[1] s01->s02 s01->s03 s01->s04 s01->s15 s02->s01 s02->s03
[7] s02->s09 s02->s10 s03->s01 s03->s04 s03->s05 s03->s08
[13] s03->s10 s03->s11 s03->s12 s04->s03 s04->s06 s04->s11
[19] s04->s12 s04->s17 s05->s01 s05->s02 s05->s09 s05->s15
[25] s06->s06 s06->s16 s06->s17 s07->s03 s07->s08 s07->s10
[31] s07->s14 s08->s03 s08->s07 s08->s09 s09->s10 s10->s03
[37] s12->s06 s12->s13 s12->s14 s13->s12 s13->s17 s14->s11
[43] s14->s13 s15->s01 s15->s04 s15->s06 s16->s06 s16->s17
[49] s17->s04
V(net) # The vertices of the "net" object
+ 17/17 vertices, named, from d431b72:
[1] s01 s02 s03 s04 s05 s06 s07 s08 s09 s10 s11 s12 s13 s14
[15] s15 s16 s17
E(net)$type # Edge attribute "type"
[1] "hyperlink" "hyperlink" "hyperlink" "mention"
[5] "hyperlink" "hyperlink" "hyperlink" "hyperlink"
[9] "hyperlink" "hyperlink" "hyperlink" "hyperlink"
[13] "mention" "hyperlink" "hyperlink" "hyperlink"
[17] "mention" "mention" "hyperlink" "mention"
[21] "mention" "hyperlink" "hyperlink" "mention"
[25] "hyperlink" "hyperlink" "mention" "mention"
[29] "mention" "hyperlink" "mention" "hyperlink"
[33] "mention" "mention" "mention" "hyperlink"
[37] "mention" "hyperlink" "mention" "hyperlink"
[41] "mention" "mention" "mention" "hyperlink"
[45] "hyperlink" "hyperlink" "hyperlink" "mention"
[49] "hyperlink"
V(net)$media # Vertex attribute "media"
[1] "NY Times" "Washington Post"
[3] "Wall Street Journal" "USA Today"
[5] "LA Times" "New York Post"
[7] "CNN" "MSNBC"
[9] "FOX News" "ABC"
[11] "BBC" "Yahoo News"
[13] "Google News" "Reuters.com"
[15] "NYTimes.com" "WashingtonPost.com"
[17] "AOL.com"
根據(jù)屬性查找節(jié)點(diǎn)和邊:
V(net)[media=="BBC"]
+ 1/17 vertex, named, from d431b72:
[1] s11
E(net)[type=="mention"]
+ 20/49 edges from d431b72 (vertex names):
[1] s01->s15 s03->s10 s04->s06 s04->s11 s04->s17 s05->s01
[7] s05->s15 s06->s17 s07->s03 s07->s08 s07->s14 s08->s07
[13] s08->s09 s09->s10 s12->s06 s12->s14 s13->s17 s14->s11
[19] s14->s13 s16->s17
根據(jù)索引查找節(jié)點(diǎn)和邊:
net[1,]
s01 s02 s03 s04 s05 s06 s07 s08 s09 s10 s11 s12 s13 s14 s15
0 22 22 21 0 0 0 0 0 0 0 0 0 0 20
s16 s17
0 0
> net[5,7]
[1] 0
從igraph網(wǎng)絡(luò)中提取一個(gè)邊列表或矩陣也很容易:
head(as_edgelist(net, names=T))
[,1] [,2]
[1,] "s01" "s02"
[2,] "s01" "s03"
[3,] "s01" "s04"
[4,] "s01" "s15"
[5,] "s02" "s01"
[6,] "s02" "s03"
as_adjacency_matrix(net, attr="weight")
17 x 17 sparse Matrix of class "dgCMatrix"
[[ suppressing 17 column names ‘s01’, ‘s02’, ‘s03’ ... ]]
s01 . 22 22 21 . . . . . . . . . . 20 . .
s02 23 . 21 . . . . . 1 5 . . . . . . .
s03 21 . . 22 1 . . 4 . 2 1 1 . . . . .
s04 . . 23 . . 1 . . . . 22 3 . . . . 2
s05 1 21 . . . . . . 2 . . . . . 21 . .
s06 . . . . . 1 . . . . . . . . . 21 21
s07 . . 1 . . . . 22 . 21 . . . 4 . . .
s08 . . 2 . . . 21 . 23 . . . . . . . .
s09 . . . . . . . . . 21 . . . . . . .
s10 . . 2 . . . . . . . . . . . . . .
s11 . . . . . . . . . . . . . . . . .
s12 . . . . . 2 . . . . . . 22 22 . . .
s13 . . . . . . . . . . . 21 . . . . 1
s14 . . . . . . . . . . 1 . 21 . . . .
s15 22 . . 1 . 4 . . . . . . . . . . .
s16 . . . . . 23 . . . . . . . . . . 21
s17 . . . 4 . . . . . . . . . . . . .
也可以轉(zhuǎn)化為data frames
head(as_data_frame(net, what="edges"))
from to type weight
1 s01 s02 hyperlink 22
2 s01 s03 hyperlink 22
3 s01 s04 hyperlink 21
4 s01 s15 mention 20
5 s02 s01 hyperlink 23
6 s02 s03 hyperlink 21
head(as_data_frame(net, what="vertices"))
name media media.type type.label
s01 s01 NY Times 1 Newspaper
s02 s02 Washington Post 1 Newspaper
s03 s03 Wall Street Journal 1 Newspaper
s04 s04 USA Today 1 Newspaper
s05 s05 LA Times 1 Newspaper
s06 s06 New York Post 1 Newspaper
audience.size
s01 20
s02 25
s03 30
s04 32
s05 20
s06 50
現(xiàn)在我們有了igraph網(wǎng)絡(luò)對象垄提,讓我們首先嘗試?yán)L制它榔袋。
plot(net) # not pretty!
看起來不太好。讓我們通過移除圖中的循環(huán)來修復(fù)問題铡俐。
# Removing loops from the graph:
net <- simplify(net, remove.multiple = F, remove.loops = T)
# Let's and reduce the arrow size and remove the labels:
plot(net, edge.arrow.size=.4,vertex.label=NA)
第二個(gè)數(shù)據(jù)集:矩陣
我們的第二個(gè)數(shù)據(jù)集是新聞媒體和消費(fèi)者之間的鏈接網(wǎng)絡(luò)凰兑。它包括兩個(gè)文件“Dataset2-Media-Example-NODES”。csv”和“Dataset2-Media-Example-EDGES.csv”
# Read in the data:
nodes2 <- read.csv("./Data files/Dataset2-Media-User-Example-NODES.csv", header=T, as.is=T)
links2 <- read.csv("./Data files/Dataset2-Media-User-Example-EDGES.csv", header=T, row.names=1)
# Examine the data:
head(nodes2)
id media media.type media.name audience.size
1 s01 NYT 1 Newspaper 20
2 s02 WaPo 1 Newspaper 25
3 s03 WSJ 1 Newspaper 30
4 s04 USAT 1 Newspaper 32
5 s05 LATimes 1 Newspaper 20
6 s06 CNN 2 TV 56
head(links2)
U01 U02 U03 U04 U05 U06 U07 U08 U09 U10 U11 U12 U13 U14
s01 1 1 1 0 0 0 0 0 0 0 0 0 0 0
s02 0 0 0 1 1 0 0 0 0 0 0 0 0 0
s03 0 0 0 0 0 1 1 1 1 0 0 0 0 0
s04 0 0 0 0 0 0 0 0 1 1 1 0 0 0
s05 0 0 0 0 0 0 0 0 0 0 1 1 1 0
s06 0 0 0 0 0 0 0 0 0 0 0 0 1 1
U15 U16 U17 U18 U19 U20
s01 0 0 0 0 0 0
s02 0 0 0 0 0 1
s03 0 0 0 0 0 0
s04 0 0 0 0 0 0
s05 0 0 0 0 0 0
s06 0 0 1 0 0 0
Two-mode (bipartite) networks in igraph
接下來审丘,我們將把第二個(gè)網(wǎng)絡(luò)轉(zhuǎn)換為igraph對象吏够。
我們可以看到,links2是一個(gè)雙模式網(wǎng)絡(luò)的鄰接矩陣滩报。雙模圖或二部圖有兩種不同類型的參與者和連接锅知,它們穿過,但不是在每種類型內(nèi)脓钾。我們的第二個(gè)媒體例子就是這樣的網(wǎng)絡(luò)售睹,研究新聞來源和他們的消費(fèi)者之間的聯(lián)系。
links2 <- as.matrix(links2)
> dim(links2)
[1] 10 20
> dim(nodes2)
[1] 30 5
# Create an igraph network object from the two-mode matrix:
net2 <- graph_from_incidence_matrix(links2)
# A built-in vertex attribute 'type' shows which mode vertices belong to.
table(V(net2)$type)
FALSE TRUE
10 20
plot(net2,vertex.label=NA)
用igraph繪圖:網(wǎng)絡(luò)繪圖有很多你可以設(shè)置的參數(shù)可训,包括節(jié)點(diǎn)選項(xiàng)(從頂點(diǎn)開始)和邊選項(xiàng)(從邊開始)昌妹。下面是所選選項(xiàng)的列表捶枢,但你也可以查看?igraph。繪圖以獲取更多信息飞崖。
NODES
vertex.color Node color
vertex.frame.color Node border color
vertex.shape One of “none”, “circle”, “square”, “csquare”, “rectangle”
“crectangle”, “vrectangle”, “pie”, “raster”, or “sphere”
vertex.size Size of the node (default is 15)
vertex.size2 The second size of the node (e.g. for a rectangle)
vertex.label Character vector used to label the nodes
vertex.label.family Font family of the label (e.g.“Times”, “Helvetica”)
vertex.label.font Font: 1 plain, 2 bold, 3, italic, 4 bold italic, 5 symbol
vertex.label.cex Font size (multiplication factor, device-dependent)
vertex.label.dist Distance between the label and the vertex
vertex.label.degree The position of the label in relation to the vertex, where
0 is right, “pi” is left, “pi/2” is below, and “-pi/2” is above
EDGES
edge.color Edge color
edge.width Edge width, defaults to 1
edge.arrow.size Arrow size, defaults to 1
edge.arrow.width Arrow width, defaults to 1
edge.lty Line type, could be 0 or “blank”, 1 or “solid”, 2 or “dashed”,
3 or “dotted”, 4 or “dotdash”, 5 or “l(fā)ongdash”, 6 or “twodash”
edge.label Character vector used to label edges
edge.label.family Font family of the label (e.g.“Times”, “Helvetica”)
edge.label.font Font: 1 plain, 2 bold, 3, italic, 4 bold italic, 5 symbol
edge.label.cex Font size for edge labels
edge.curved Edge curvature, range 0-1 (FALSE sets it to 0, TRUE to 0.5)
arrow.mode Vector specifying whether edges should have arrows,
possible values: 0 no arrow, 1 back, 2 forward, 3 both
OTHER
margin Empty space margins around the plot, vector with length 4
frame if TRUE, the plot will be framed
main If set, adds a title to the plot
sub If set, adds a subtitle to the plot
asp Numeric, the aspect ratio of a plot (y/x).
palette A color palette to use for vertex color
rescale Whether to rescale coordinates to [-1,1]. Default is TRUE.
# Plot with curved edges (edge.curved=.1) and reduce arrow size:
plot(net, edge.arrow.size=.4,vertex.color = 'white', edge.curved=.1)
# Set node color to orange and the border color to hex #555555
# Replace the vertex label with the node names stored in "media"
plot(net, edge.arrow.size=.2, edge.curved=0,
vertex.color="orange", vertex.frame.color="#555555",
vertex.label=V(net)$media, vertex.label.color="black",
vertex.label.cex=.7)
第二種設(shè)置屬性的方法是將它們添加到igraph對象中烂叔。假設(shè)我們想根據(jù)媒體類型為網(wǎng)絡(luò)節(jié)點(diǎn)著色,并根據(jù)度中心性(更多的鏈接->更大的節(jié)點(diǎn))調(diào)整它們的大小固歪,我們還將根據(jù)它們的權(quán)重改變邊緣的寬度长已。
# Generate colors based on media type:
colrs <- c("gray50", "tomato", "gold")
V(net)$color <- colrs[V(net)$media.type]
# Compute node degrees (#links) and use that to set node size:
deg <- degree(net, mode="all")
V(net)$size <- deg*3
# Alternatively, we can set node size based on audience size:
V(net)$size <- V(net)$audience.size*0.7
# The labels are currently node IDs.
# Setting them to NA will render no labels:
V(net)$label.color <- "black"
V(net)$label <- NA
# Set edge width based on weight:
E(net)$width <- E(net)$weight/6
#change arrow size and edge color:
E(net)$arrow.size <- .2
E(net)$edge.color <- "gray80"
# We can even set the network layout:
graph_attr(net, "layout") <- layout_with_lgl
plot(net)
# We can also override the attributes explicitly in the plot:
plot(net, edge.color="orange", vertex.color="gray50")
有時(shí),特別是在語義網(wǎng)絡(luò)中昼牛,我們可能只對繪制節(jié)點(diǎn)的標(biāo)簽感興趣:
plot(net, vertex.shape="none", vertex.label=V(net)$media,
vertex.label.font=2, vertex.label.color="gray40",
vertex.label.cex=.7, edge.color="gray85")
讓我們根據(jù)源節(jié)點(diǎn)的顏色為圖的邊著色术瓮。我們可以使用ends() igraph函數(shù)獲得每條邊的起始節(jié)點(diǎn)。它返回es參數(shù)中列出的邊的起始點(diǎn)和結(jié)束點(diǎn)贰健。names參數(shù)控制函數(shù)是返回邊名還是id胞四。
edge.start <- ends(net, es=E(net), names=F)[,1]
edge.col <- V(net)$color[edge.start]
plot(net, edge.color=edge.col, edge.curved=.1)
網(wǎng)絡(luò)圖的布局
網(wǎng)絡(luò)布局是一種簡單的算法,它返回網(wǎng)絡(luò)中每個(gè)節(jié)點(diǎn)的坐標(biāo)伶椿。
為了研究布局辜伟,我們將生成一個(gè)稍微大一點(diǎn)的100節(jié)點(diǎn)的圖。我們使用sample_pa()函數(shù)脊另,它生成一個(gè)簡單的圖导狡,從一個(gè)節(jié)點(diǎn)開始,并根據(jù)預(yù)設(shè)的優(yōu)先連接級別添加更多節(jié)點(diǎn)和鏈接(barabsi - albert模型)偎痛。
net.bg <- sample_pa(100, 1.2)
V(net.bg)$size <- 8
V(net.bg)$frame.color <- "white"
V(net.bg)$color <- "orange"
V(net.bg)$label <- ""
E(net.bg)$arrow.mode <- 0
plot(net.bg)
您可以在plot功能中設(shè)置布局:
plot(net.bg, layout=layout_randomly)
# Or calculate the vertex coordinates in advance:
l <- layout_in_circle(net.bg)
plot(net.bg, layout=l)
# Randomly placed vertices
l <- layout_randomly(net.bg)
plot(net.bg, layout=l)
#3D sphere layout
l <- layout_on_sphere(net.bg)
plot(net.bg, layout=l)
l <- cbind(1:vcount(net.bg), c(1, vcount(net.bg):2))
plot(net.bg, layout=l)
Fruchterman-Reingold是最常用的強(qiáng)制定向布局算法之一旱捧。
強(qiáng)制定向布局試圖得到一個(gè)好看的圖形,其中邊的長度相似踩麦,并盡可能不交叉枚赡。他們把圖形模擬成一個(gè)物理系統(tǒng)。節(jié)點(diǎn)是帶電粒子谓谦,當(dāng)它們靠得太近時(shí)會(huì)相互排斥贫橙。
這些邊就像彈簧一樣吸引連接的節(jié)點(diǎn)靠近。因此反粥,節(jié)點(diǎn)均勻分布在整個(gè)圖表區(qū)域卢肃,布局直觀,節(jié)點(diǎn)間的聯(lián)系越多才顿,節(jié)點(diǎn)間的距離越近莫湘。這些算法的缺點(diǎn)是它們相當(dāng)慢,因此很少用于大于1000個(gè)頂點(diǎn)的圖娜膘。
l <- layout_with_fr(net.bg)
plot(net.bg, layout=l)
對于強(qiáng)制定向布局逊脯,您可以使用niter參數(shù)來控制要執(zhí)行的迭代次數(shù)。默認(rèn)設(shè)置為500次迭代竣贪。對于大型圖军洼,可以降低這個(gè)數(shù)字巩螃,以更快地獲得結(jié)果,并檢查它們是否合理匕争。
l <- layout_with_fr(net.bg, niter=50)
plot(net.bg, layout=l
布局也可以解釋邊的權(quán)重避乏。您可以設(shè)置“權(quán)重”參數(shù),以增加由較重邊連接的節(jié)點(diǎn)之間的吸引力甘桑。
ws <- c(1, rep(100, ecount(net.bg)-1))
lw <- layout_with_fr(net.bg, weights=ws)
plot(net.bg, layout=lw)
您還將注意到拍皮,F(xiàn)ruchterman-Reingold布局是不確定的——不同的運(yùn)行將導(dǎo)致略微不同的配置。將布局保存在l中可以多次得到完全相同的結(jié)果跑杭,如果您想繪制圖的時(shí)間演化或不同的關(guān)系铆帽,并且希望節(jié)點(diǎn)在多個(gè)圖中保持在相同的位置,那么這將非常有用德谅。
par(mfrow=c(2,2), mar=c(1,1,1,1))
plot(net.bg, layout=layout_with_fr)
plot(net.bg, layout=layout_with_fr)
plot(net.bg, layout=l)
plot(net.bg, layout=l)
默認(rèn)情況下爹橱,圖形的坐標(biāo)將被重新標(biāo)定為x和y的[-1,1]區(qū)間。您可以使用參數(shù)rescale=FALSE進(jìn)行更改窄做,并通過將坐標(biāo)乘以一個(gè)標(biāo)量手動(dòng)重新標(biāo)定您的圖形愧驱。您可以使用norm_coords使用您想要的邊界來規(guī)范化繪圖。通過這種方式椭盏,您可以創(chuàng)建更緊湊或更分散的布局版本组砚。
# Get the layout coordinates:
l <- layout_with_fr(net.bg)
# Normalize them so that they are in the -1, 1 interval:
l <- norm_coords(l, ymin=-1, ymax=1, xmin=-1, xmax=1)
par(mfrow=c(2,2), mar=c(0,0,0,0))
plot(net.bg, rescale=F, layout=l*0.4)
plot(net.bg, rescale=F, layout=l*0.8)
plot(net.bg, rescale=F, layout=l*1.2)
plot(net.bg, rescale=F, layout=l*1.6)
有些布局有3D版本,你可以使用參數(shù)dim=3掏颊。如您所料糟红,3D布局返回一個(gè)包含3列的矩陣,其中包含每個(gè)節(jié)點(diǎn)的X蚯舱、Y和Z坐標(biāo)改化。
# Some layouts have 3D versions that you can use with parameter 'dim=3'
l <- layout_with_fr(net.bg, dim=3)
plot(net.bg, layout=l)
# Another popular force-directed algorithm that produces nice results for
# connected graphs is Kamada Kawai. Like Fruchterman Reingold, it attempts to
# minimize the energy in a spring system.
l <- layout_with_kk(net.bg)
plot(net.bg, layout=l)
Graphopt是在igraph中實(shí)現(xiàn)的一種很好的強(qiáng)制定向布局掩蛤,它使用分層來幫助實(shí)現(xiàn)大型網(wǎng)絡(luò)的可視化枉昏。
l <- layout_with_graphopt(net.bg)
plot(net.bg, layout=l)
利用現(xiàn)有的graphopt參數(shù)可以改變節(jié)點(diǎn)的質(zhì)量和電荷,以及最佳的彈簧長度和邊緣的彈簧常數(shù)揍鸟。參數(shù)名是charge(默認(rèn)值為0.001)兄裂、mass(默認(rèn)值為30)、spring阳藻。長度(缺省值為0)和彈簧晰奖。常量(默認(rèn)值為1)。調(diào)整這些參數(shù)會(huì)導(dǎo)致非常不同的圖形布局腥泥。
l1 <- layout_with_graphopt(net.bg, charge=0.02)
l2 <- layout_with_graphopt(net.bg, charge=0.00000001)
par(mfrow=c(1,2), mar=c(1,1,1,1))
plot(net.bg, layout=l1)
plot(net.bg, layout=l2)
LGL算法適用于大型連通圖匾南。在這里,您還可以指定一個(gè)根:一個(gè)將放置在布局中間的節(jié)點(diǎn)蛔外。
# The LGL algorithm is for large connected graphs. Here you can specify a root -
# the node that will be placed in the middle of the layout.
plot(net.bg, layout=layout_with_lgl)
MDS(多維尺度)算法試圖基于節(jié)點(diǎn)之間的某種相似性或距離度量來放置節(jié)點(diǎn)蛆楞。更相似的節(jié)點(diǎn)被繪制得更接近彼此溯乒。默認(rèn)情況下,使用的度量是基于網(wǎng)絡(luò)中節(jié)點(diǎn)之間的最短路徑豹爹。我們可以通過使用我們自己的距離矩陣(無論如何定義)和參數(shù)dist來改變它裆悄。MDS布局很好,因?yàn)槲恢煤途嚯x有一個(gè)清晰的解釋臂聋。它們的問題在于視覺清晰度:節(jié)點(diǎn)通常是重疊的光稼,或者是相互疊加的。
plot(net.bg, layout=layout_with_mds)
讓我們看看所有可用的布局在igraph:
layouts <- grep("^layout_", ls("package:igraph"), value=TRUE)[-1]
# Remove layouts that do not apply to our graph.
layouts <- layouts[!grepl("bipartite|merge|norm|sugiyama|tree", layouts)]
par(mfrow=c(3,5), mar=c(1,1,1,1))
for (layout in layouts) {
print(layout)
l <- do.call(layout, list(net))
plot(net, edge.arrow.mode=0, layout=l, main=layout) }
[1] "layout_as_star"
[1] "layout_components"
[1] "layout_in_circle"
[1] "layout_nicely"
[1] "layout_on_grid"
[1] "layout_on_sphere"
[1] "layout_randomly"
[1] "layout_with_dh"
[1] "layout_with_drl"
[1] "layout_with_fr"
[1] "layout_with_gem"
[1] "layout_with_graphopt"
[1] "layout_with_kk"
[1] "layout_with_lgl"
[1] "layout_with_mds"
突出網(wǎng)絡(luò)的某個(gè)方面
注意孩等,我們的網(wǎng)絡(luò)圖仍然不是很有用艾君。我們可以識(shí)別出團(tuán)簇的類型和大小,但無法看到更多的結(jié)構(gòu)肄方,因?yàn)槲覀冋跈z查的連接太密集了腻贰。解決這個(gè)問題的一種方法是看看我們是否能使網(wǎng)絡(luò)分散化,只保留最重要的聯(lián)系扒秸,而丟棄其余的播演。
hist(links$weight)
Warning messages:
1: In doTryCatch(return(expr), name, parentenv, handler) :
invalid graphics state
2: In doTryCatch(return(expr), name, parentenv, handler) :
invalid graphics state
> mean(links$weight)
[1] 12.40816
> sd(links$weight)
[1] 9.905635
>
還有更復(fù)雜的方法來提取關(guān)鍵邊緣,但為了本練習(xí)的目的伴奥,我們將只保留權(quán)值高于網(wǎng)絡(luò)平均值的方法写烤。在igraph中,我們可以使用delete_edges(net, edges)來刪除邊:
cut.off <- mean(links$weight)
net.sp <- delete_edges(net, E(net)[weight<cut.off])
plot(net.sp, layout=layout_with_kk)
考慮這個(gè)問題的另一種方法是分別繪制兩種綁定類型(超鏈接和提及)拾徙。我們將在本教程的第5節(jié):繪制多路網(wǎng)絡(luò)洲炊。:我們還可以通過展示網(wǎng)絡(luò)地圖中的社區(qū),使其更有用:
# Community detection (by optimizing modularity over partitions):
clp <- cluster_optimal(net)
class(clp)
[1] "communities"
clp$membership
[1] 1 1 1 1 1 2 3 3 3 3 1 4 4 4 1 2 2
# Community detection returns an object of class "communities"
# which igraph knows how to plot:
plot(clp, net)
# We can also plot the communities without relying on their built-in plot:
V(net)$community <- clp$membership
colrs <- adjustcolor( c("gray50", "tomato", "gold", "yellowgreen"), alpha=.6)
plot(net, vertex.color=colrs[V(net)$community])
突出顯示特定節(jié)點(diǎn)或鏈接
有時(shí)尼啡,我們希望將可視化重點(diǎn)放在特定節(jié)點(diǎn)或節(jié)點(diǎn)組上暂衡。在我們的例子“媒體網(wǎng)絡(luò)”中,我們可以檢查來自焦點(diǎn)參與者的信息傳播崖瞭。例如狂巢,讓我們表示到紐約時(shí)報(bào)的距離。
distance函數(shù)返回一個(gè)最短路徑矩陣书聚,從v參數(shù)中列出的節(jié)點(diǎn)到to參數(shù)中包含的節(jié)點(diǎn)唧领。
dist.from.NYT <- distances(net, v=V(net)[media=="NY Times"], to=V(net), weights=NA)
# Set colors to plot the distances:
oranges <- colorRampPalette(c("dark red", "gold"))
col <- oranges(max(dist.from.NYT)+1)
col <- col[dist.from.NYT+1]
plot(net, vertex.color=col, vertex.label=dist.from.NYT, edge.arrow.size=.6,
vertex.label.color="white")
# We can also highlight paths between the nodes in the network.
# Say here between MSNBC and the New York Post:
news.path <- shortest_paths(net,
from = V(net)[media=="MSNBC"],
to = V(net)[media=="New York Post"],
output = "both") # both path nodes and edges
# Generate edge color variable to plot the path:
ecol <- rep("gray80", ecount(net))
ecol[unlist(news.path$epath)] <- "orange"
# Generate edge width variable to plot the path:
ew <- rep(2, ecount(net))
ew[unlist(news.path$epath)] <- 4
# Generate node color variable to plot the path:
vcol <- rep("gray40", vcount(net))
vcol[unlist(news.path$vpath)] <- "gold"
plot(net, vertex.color=vcol, edge.color=ecol,
edge.width=ew, edge.arrow.mode=0)
我們可以突出進(jìn)入或離開一個(gè)頂點(diǎn)的邊,例如華爾街日報(bào)雌续。對于單個(gè)節(jié)點(diǎn)斩个,使用incident(),對于多個(gè)節(jié)點(diǎn)驯杜,使用incident_edges()
inc.edges <- incident(net, V(net)[media=="Wall Street Journal"], mode="all")
# Set colors to plot the selected edges.
ecol <- rep("gray80", ecount(net))
ecol[inc.edges] <- "orange"
vcol <- rep("grey40", vcount(net))
vcol[V(net)$media=="Wall Street Journal"] <- "gold"
plot(net, vertex.color=vcol, edge.color=ecol)
WSJ說受啥,我們還可以指出一個(gè)頂點(diǎn)的近鄰。鄰居函數(shù)查找距焦點(diǎn)參與者一步之遙的所有節(jié)點(diǎn)。要查找多個(gè)節(jié)點(diǎn)的鄰居滚局,請使用adjacent_vertices()而不是neighbors()叁温。為了找到超過一步的節(jié)點(diǎn)鄰域,使用函數(shù)ego()核畴,參數(shù)順序設(shè)置為從焦點(diǎn)節(jié)點(diǎn)出發(fā)的步數(shù)膝但。
neigh.nodes <- neighbors(net, V(net)[media=="Wall Street Journal"], mode="out")
# Set colors to plot the neighbors:
vcol[neigh.nodes] <- "#ff9d00"
plot(net, vertex.color=vcol)
吸引人們注意一組節(jié)點(diǎn)的一種方法(我們以前在社區(qū)中看到過)是“標(biāo)記”它們:
par(mfrow=c(1,2))
# plot(net, mark.groups=c(1,4,5,8), mark.col="#C5E5E7", mark.border=NA)
# Another way to draw attention to a group of nodes:
plot(net, mark.groups=c(1,4,5,8), mark.col="#C5E5E7", mark.border=NA)
# Mark multiple groups:
plot(net, mark.groups=list(c(1,4,5,8), c(15:17)),
mark.col=c("#C5E5E7","#ECD89A"), mark.border=NA)
交互式繪制與tkplot
R和igraph允許對網(wǎng)絡(luò)進(jìn)行交互式繪圖。如果您想稍微調(diào)整一個(gè)小圖形的布局谤草,這可能是一個(gè)有用的選項(xiàng)跟束。在手動(dòng)調(diào)整布局之后,您可以獲得節(jié)點(diǎn)的坐標(biāo)丑孩,并將它們用于其他圖形冀宴。
tkid <- tkplot(net) #tkid is the id of the tkplot
手動(dòng)調(diào)節(jié)后之后,提取出來:
l <- tkplot.getcoords(tkid) # grab the coordinates from tkplot
plot(net, layout=l)
繪制雙模網(wǎng)絡(luò)
你可能還記得温学,我們的第二個(gè)媒體例子是一個(gè)雙模式網(wǎng)絡(luò)略贮,研究新聞來源和他們的消費(fèi)者之間的聯(lián)系。
> head(nodes2)
id media media.type media.name audience.size
1 s01 NYT 1 Newspaper 20
2 s02 WaPo 1 Newspaper 25
3 s03 WSJ 1 Newspaper 30
4 s04 USAT 1 Newspaper 32
5 s05 LATimes 1 Newspaper 20
6 s06 CNN 2 TV 56
Warning message:
In rm(list = cmd, envir = .tkplot.env) : 找不到對象'tkp.3'
> head(links2)
U01 U02 U03 U04 U05 U06 U07 U08 U09 U10 U11 U12 U13 U14
s01 1 1 1 0 0 0 0 0 0 0 0 0 0 0
s02 0 0 0 1 1 0 0 0 0 0 0 0 0 0
s03 0 0 0 0 0 1 1 1 1 0 0 0 0 0
s04 0 0 0 0 0 0 0 0 1 1 1 0 0 0
s05 0 0 0 0 0 0 0 0 0 0 1 1 1 0
s06 0 0 0 0 0 0 0 0 0 0 0 0 1 1
U15 U16 U17 U18 U19 U20
s01 0 0 0 0 0 0
s02 0 0 0 0 0 1
s03 0 0 0 0 0 0
s04 0 0 0 0 0 0
s05 0 0 0 0 0 0
s06 0 0 1 0 0 0
net2
IGRAPH 8d46ba2 UN-B 30 31 --
+ attr: type (v/l), name (v/c)
+ edges from 8d46ba2 (vertex names):
[1] s01--U01 s01--U02 s01--U03 s02--U04 s02--U05 s02--U20
[7] s03--U06 s03--U07 s03--U08 s03--U09 s04--U09 s04--U10
[13] s04--U11 s05--U11 s05--U12 s05--U13 s06--U13 s06--U14
[19] s06--U17 s07--U14 s07--U15 s07--U16 s08--U16 s08--U17
[25] s08--U18 s08--U19 s09--U06 s09--U19 s09--U20 s10--U01
[31] s10--U11
> plot(net2)
與單模式網(wǎng)絡(luò)一樣仗岖,我們可以修改網(wǎng)絡(luò)對象逃延,以包括在繪制網(wǎng)絡(luò)時(shí)默認(rèn)使用的可視化屬性。注意轧拄,這次我們還將改變節(jié)點(diǎn)的形狀——媒體輸出將是方形的揽祥,而它們的用戶將是圓形的。
# This time we will make nodes look different based on their type.
# Media outlets are blue squares, audience nodes are orange circles:
V(net2)$color <- c("steel blue", "orange")[V(net2)$type+1]
V(net2)$shape <- c("square", "circle")[V(net2)$type+1]
# Media outlets will have name labels, audience members will not:
V(net2)$label <- ""
V(net2)$label[V(net2)$type==F] <- nodes2$media[V(net2)$type==F]
V(net2)$label.cex=.6
V(net2)$label.font=2
plot(net2, vertex.label.color="white", vertex.size=(2-V(net2)$type)*8)
在igraph中檩电,也有一個(gè)特殊的二分圖(盡管它并不總是工作得很好拄丰,而且你最好自己生成一個(gè)雙模式的二分圖)。
plot(net2, vertex.label=NA, vertex.size=7, layout=layout_as_bipartite)
par(mar=c(0,0,0,0))
plot(net2, vertex.shape="none", vertex.label=nodes2$media,
vertex.label.color=V(net2)$color, vertex.label.font=2,
vertex.label.cex=.95, edge.color="gray70", edge.width=2)
還可以自己加圖標(biāo)
library("png")
img.1 <- readPNG("./Data files/images/news.png")
img.2 <- readPNG("./Data files/images/user.png")
V(net2)$raster <- list(img.1, img.2)[V(net2)$type+1]
par(mar=c(3,3,3,3))
plot(net2, vertex.shape="raster", vertex.label=NA,
vertex.size=16, vertex.size2=16, edge.width=2)
順便說一下俐末,我們還可以添加任何我們想要的圖像到繪圖料按。例如,許多網(wǎng)絡(luò)圖可以通過茶杯里一只小狗的照片得到很大的改善卓箫,這就有點(diǎn)調(diào)皮了啊载矿。
img.3 <- readPNG("./Data files/images/puppy.png")
rasterImage(img.3, xleft=-1.4, xright=-0.4, ybottom=-1.4, ytop=-0.2)
我們也可以為二模式網(wǎng)絡(luò)生成和繪制二部圖投影:通過將網(wǎng)絡(luò)矩陣乘以它的轉(zhuǎn)置矩陣,或者使用igraph的bipartite.projection()函數(shù)丽柿,共同隸屬關(guān)系很容易計(jì)算恢准。
# We can also generate and plot bipartite projections for the two-mode network:
# (co-memberships are easy to calculate by multiplying the network matrix by
# its transposed matrix, or using igraph's bipartite.projection function)
net2.bp <- bipartite.projection(net2)
# We can calculate the projections manually as well:
# as_incidence_matrix(net2) %*% t(as_incidence_matrix(net2))
# t(as_incidence_matrix(net2)) %*% as_incidence_matrix(net2)
par(mfrow=c(1,2))
plot(net2.bp$proj1, vertex.label.color="black", vertex.label.dist=1,
vertex.label=nodes2$media[!is.na(nodes2$media.type)])
plot(net2.bp$proj2, vertex.label.color="black", vertex.label.dist=1,
vertex.label=nodes2$media[ is.na(nodes2$media.type)])
dev.off()
繪制多復(fù)路網(wǎng)絡(luò)
library("igraph")
E(net)$width <- 2
plot(net, edge.color=c("dark red", "slategrey")[(E(net)$type=="hyperlink")+1],
vertex.color="gray40", layout=layout_in_circle, edge.curved=.3)
# Another way to delete edges using the minus operator:
net.m <- net - E(net)[E(net)$type=="hyperlink"]
net.h <- net - E(net)[E(net)$type=="mention"]
# Plot the two links separately:
par(mfrow=c(1,2))
plot(net.h, vertex.color="orange", layout=layout_with_fr, main="Tie: Hyperlink")
plot(net.m, vertex.color="lightsteelblue2", layout=layout_with_fr, main="Tie: Mention")
dev.off()
# Make sure the nodes stay in the same place in both plots:
par(mfrow=c(1,2),mar=c(1,1,4,1))
l <- layout_with_fr(net)
plot(net.h, vertex.color="orange", layout=l, main="Tie: Hyperlink")
plot(net.m, vertex.color="lightsteelblue2", layout=l, main="Tie: Mention")
在我們的示例網(wǎng)絡(luò)中,碰巧沒有由多種連接類型連接的節(jié)點(diǎn)對甫题。也就是說,在同一家新聞媒體之間涂召,我們從來沒有同時(shí)存在“超鏈接”和“提及”的聯(lián)系坠非。然而,這在多路網(wǎng)絡(luò)中很容易發(fā)生果正。
將多個(gè)圖可視化的一個(gè)挑戰(zhàn)是炎码,相同的兩個(gè)節(jié)點(diǎn)之間的多個(gè)邊可能會(huì)以一種不可能清楚地看到它們的方式疊加在一起盟迟。例如,讓我們生成一個(gè)非常簡單的多路網(wǎng)絡(luò)潦闲,其中有兩個(gè)節(jié)點(diǎn)和三個(gè)節(jié)點(diǎn)之間的紐帶:
multigtr <- graph( edges=c(1,2, 1,2, 1,2), n=2 )
l <- layout_with_kk(multigtr)
# Let's just plot the graph:
plot(multigtr, vertex.color="lightsteelblue", vertex.frame.color="white",
vertex.size=40, vertex.shape="circle", vertex.label=NA,
edge.color=c("gold", "tomato", "yellowgreen"), edge.width=10,
edge.arrow.size=5, edge.curved=0.1, layout=l)
因?yàn)閳D中所有的邊都有相同的曲率攒菠,所以它們相互重疊,這樣我們只能看到其中一條歉闰。我們能做的就是給每條邊分配一個(gè)不同的曲率辖众。igraph中一個(gè)名為curve_multiple的有用函數(shù)可以幫助我們解決這個(gè)問題。對于圖G, curv .multiple(G)將為每條邊生成一個(gè)曲率和敬,使可見性最大化凹炸。
plot(multigtr, vertex.color="lightsteelblue", vertex.frame.color="white",
vertex.size=40, vertex.shape="circle", vertex.label=NA,
edge.color=c("gold", "tomato", "yellowgreen"), edge.width=10,
edge.arrow.size=5, edge.curved=curve_multiple(multigtr), layout=l)
超越igraph : Statnet, ggraph, and simple charts
igraph包只是r中許多可用的網(wǎng)絡(luò)可視化選項(xiàng)之一。本節(jié)提供幾個(gè)快速示例來說明其他可用的靜態(tài)網(wǎng)絡(luò)可視化方法昼弟。
使用network 包進(jìn)行繪圖與使用igraph非常相似——盡管表示法略有不同(一組全新的參數(shù)名稱!)這個(gè)包還使用較少的通過修改網(wǎng)絡(luò)對象獲得的默認(rèn)控件啤它,以及在繪圖函數(shù)中使用更顯式的參數(shù)。
下面是一個(gè)使用(現(xiàn)在已經(jīng)很熟悉了)媒體網(wǎng)絡(luò)的快速示例舱痘。我們首先將數(shù)據(jù)轉(zhuǎn)換為Statnet包系列(包括network变骡、sna、ergm芭逝、stergm和其他)使用的網(wǎng)絡(luò)格式锣光。
在igraph中,我們可以從一個(gè)邊表铝耻、一個(gè)鄰接矩陣或一個(gè)關(guān)聯(lián)矩陣中生成一個(gè)“網(wǎng)絡(luò)”對象誊爹。您可以使用? edgesett .constructors來獲得細(xì)節(jié)。這里我們將使用邊列表和節(jié)點(diǎn)屬性數(shù)據(jù)幀來創(chuàng)建網(wǎng)絡(luò)對象瓢捉。這里要特別注意的是忽略频丘。eval參數(shù)。默認(rèn)情況下它被設(shè)置為TRUE泡态,該設(shè)置會(huì)導(dǎo)致網(wǎng)絡(luò)對象忽略邊的權(quán)值搂漠。
library("network")
head(links)
from to type weight
1 s01 s02 hyperlink 22
2 s01 s03 hyperlink 22
3 s01 s04 hyperlink 21
4 s01 s15 mention 20
5 s02 s01 hyperlink 23
6 s02 s03 hyperlink 21
> head(nodes)
id media media.type type.label audience.size
1 s01 NY Times 1 Newspaper 20
2 s02 Washington Post 1 Newspaper 25
3 s03 Wall Street Journal 1 Newspaper 30
4 s04 USA Today 1 Newspaper 32
5 s05 LA Times 1 Newspaper 20
6 s06 New York Post 1 Newspaper 50
# Remember to set the ignore.eval to F for weighted networks.
net3 <- network(links, vertex.attr=nodes, matrix.type="edgelist",
loops=F, multiple=F, ignore.eval = F)
net3
Network attributes:
vertices = 17
directed = TRUE
hyper = FALSE
loops = FALSE
multiple = FALSE
bipartite = FALSE
total edges= 49
missing edges= 0
non-missing edges= 49
Vertex attribute names:
audience.size id media media.type type.label vertex.names
Edge attribute names:
type weight
net3[,]
s01 s02 s03 s04 s05 s06 s07 s08 s09 s10 s11 s12 s13 s14
s01 0 1 1 1 0 0 0 0 0 0 0 0 0 0
s02 1 0 1 0 0 0 0 0 1 1 0 0 0 0
s03 1 0 0 1 1 0 0 1 0 1 1 1 0 0
s04 0 0 1 0 0 1 0 0 0 0 1 1 0 0
s05 1 1 0 0 0 0 0 0 1 0 0 0 0 0
s06 0 0 0 0 0 1 0 0 0 0 0 0 0 0
s07 0 0 1 0 0 0 0 1 0 1 0 0 0 1
s08 0 0 1 0 0 0 1 0 1 0 0 0 0 0
s09 0 0 0 0 0 0 0 0 0 1 0 0 0 0
s10 0 0 1 0 0 0 0 0 0 0 0 0 0 0
s11 0 0 0 0 0 0 0 0 0 0 0 0 0 0
s12 0 0 0 0 0 1 0 0 0 0 0 0 1 1
s13 0 0 0 0 0 0 0 0 0 0 0 1 0 0
s14 0 0 0 0 0 0 0 0 0 0 1 0 1 0
s15 1 0 0 1 0 1 0 0 0 0 0 0 0 0
s16 0 0 0 0 0 1 0 0 0 0 0 0 0 0
s17 0 0 0 1 0 0 0 0 0 0 0 0 0 0
s15 s16 s17
s01 1 0 0
s02 0 0 0
s03 0 0 0
s04 0 0 1
s05 1 0 0
s06 0 1 1
s07 0 0 0
s08 0 0 0
s09 0 0 0
s10 0 0 0
s11 0 0 0
s12 0 0 0
s13 0 0 1
s14 0 0 0
s15 0 0 0
s16 0 0 1
s17 0 0 0
> net3 %n% "net.name" <- "Media Network" # network attribute
> net3 %v% "media" # Node attribute
[1] "NY Times" "Washington Post"
[3] "Wall Street Journal" "USA Today"
[5] "LA Times" "New York Post"
[7] "CNN" "MSNBC"
[9] "FOX News" "ABC"
[11] "BBC" "Yahoo News"
[13] "Google News" "Reuters.com"
[15] "NYTimes.com" "WashingtonPost.com"
[17] "AOL.com"
> net3 %e% "type" # Node attribute
[1] "hyperlink" "hyperlink" "hyperlink" "mention"
[5] "hyperlink" "hyperlink" "hyperlink" "hyperlink"
[9] "hyperlink" "hyperlink" "hyperlink" "hyperlink"
[13] "mention" "hyperlink" "hyperlink" "hyperlink"
[17] "mention" "mention" "hyperlink" "mention"
[21] "mention" "hyperlink" "hyperlink" "mention"
[25] "hyperlink" "hyperlink" "mention" "mention"
[29] "mention" "hyperlink" "mention" "hyperlink"
[33] "mention" "mention" "mention" "hyperlink"
[37] "mention" "hyperlink" "mention" "hyperlink"
[41] "mention" "mention" "mention" "hyperlink"
[45] "hyperlink" "hyperlink" "hyperlink" "mention"
[49] "hyperlink"
net3 %v% "col" <- c("gray70", "tomato", "gold")[net3 %v% "media.type"]
# plot the network:
plot(net3, vertex.cex=(net3 %v% "audience.size")/7, vertex.col="col")
注意,與igraph中一樣,plot返回節(jié)點(diǎn)位置坐標(biāo)。您可以使用coord參數(shù)在其他繪圖中使用它們肝匆。
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)
network 包還提供了交互式編輯情節(jié)的選項(xiàng)羹铅,通過設(shè)置參數(shù)interactive=T:
plot(net3, vertex.cex=(net3 %v% "audience.size")/7, vertex.col="col", interactive=T)
ggraph
ggplot2包及其擴(kuò)展以提供最有意義的結(jié)構(gòu)化和高級方法來可視化r中的數(shù)據(jù)而聞名。在ggplot2中傀顾,您可以從各種可視化構(gòu)建塊中選擇,并將它們逐個(gè)添加到圖形中,一次一層拣度。
ggraph包采用了這一原理,并將其擴(kuò)展到網(wǎng)絡(luò)數(shù)據(jù)。在本節(jié)中抗果,我們只討論基礎(chǔ)知識(shí)筋帖,而不提供圖形方法語法的詳細(xì)概述。為了更深入地了解它冤馏,最好先熟悉ggplot2日麸,然后學(xué)習(xí)ggraph的細(xì)節(jié)。
一個(gè)好消息是逮光,我們可以直接將igraph對象與ggraph包一起使用代箭。下面的代碼獲取數(shù)據(jù)并為節(jié)點(diǎn)和鏈接添加單獨(dú)的層。
library(ggraph)
library(igraph)
# We can use our 'net' igraph object directly with the 'ggraph' package.
# The following code gets the data and adds layers for nodes and links.
ggraph(net) +
geom_edge_link() + # add edges to the plot
geom_node_point() # add nodes to the plot
:在這里睦霎,您還將認(rèn)識(shí)一些熟悉的網(wǎng)絡(luò)布局梢卸,從igraph繪圖:“星形”,“圓”副女,“網(wǎng)格”蛤高,“球面”,“kk”碑幅,“fr”戴陡,“mds”,“l(fā)gl”等沟涨。
ggraph(net, layout="lgl") +
geom_edge_link() +
ggtitle("Look ma, no nodes!") # add title to the plot
在這里恤批,我們可以對直邊使用geom_edge_link(),對彎曲邊使用geom_edge_arc()裹赴,當(dāng)我們希望確保任何重疊的多重邊將被扇形展開時(shí)喜庞,可以使用geom_edge_fan()。
在其他包中棋返,我們可以通過使用關(guān)鍵函數(shù)參數(shù)來設(shè)置網(wǎng)絡(luò)圖的可視化屬性延都。例如,節(jié)點(diǎn)有顏色睛竣、填充晰房、形狀、大小和描邊射沟。邊有顏色殊者、寬度和線條類型。這里也是alpha參數(shù)控制透明度验夯。
ggraph(net, layout="lgl") +
geom_edge_fan(color="gray50", width=0.8, alpha=0.5) +
geom_node_point(color=V(net)$color, size=8) +
theme_minimal()
與ggplot2一樣猖吴,我們可以向情節(jié)中添加不同的主題。為了更清晰的外觀簿姨,您可以使用最小或空主題距误,并使用theme_minimal()或theme_void()簸搞。
ggraph(net, layout = 'linear') +
geom_edge_arc(color = "orange", width=0.7) +
geom_node_point(size=5, color="gray50") +
theme_void()
ggraph包還使用了映射美學(xué)的傳統(tǒng)ggplot2方法:也就是說扁位,指定哪些數(shù)據(jù)元素應(yīng)該對應(yīng)于圖形的不同視覺屬性准潭。這是使用aes()函數(shù)完成的,該函數(shù)匹配數(shù)據(jù)中的可視參數(shù)和屬性名域仇。在下面的代碼中刑然,edge屬性的類型和節(jié)點(diǎn)屬性的受眾。大小從igraph對象中包含的數(shù)據(jù)中提取暇务。
ggraph(net, layout="lgl") +
geom_edge_link(aes(color = type)) + # colors by edge type
geom_node_point(aes(size = audience.size)) + # size by audience size
theme_void()
您可以在上面看到關(guān)于ggplot2和ggraph的一個(gè)偉大之處是泼掠,它們會(huì)自動(dòng)生成圖例,這使得情節(jié)更容易解釋垦细。
我們可以使用geom_node_text()或geom_node_label()來添加帶有節(jié)點(diǎn)標(biāo)簽的層择镇,它們與ggplot2中的類似函數(shù)相對應(yīng)。
ggraph(net, layout = 'lgl') +
geom_edge_arc(color="gray", curvature=0.3) +
geom_node_point(color="orange", aes(size = audience.size)) +
geom_node_text(aes(label = media), color="gray50", repel=T) +
theme_void()
其他方法
# First, we'll extract a matrix from our igraph network object.
netm <- as_adjacency_matrix(net, attr="weight", sparse=F)
colnames(netm) <- V(net)$media
rownames(netm) <- V(net)$media
# Generate a color palette to use in the heatmap:
palf <- colorRampPalette(c("gold", "dark orange"))
# The Rowv & Colv parameters turn dendrograms on and off
heatmap(netm[,17:1], Rowv = NA, Colv = NA, col = palf(20),
scale="none", margins=c(10,10) )
# Degree distribution
deg.dist <- degree_distribution(net, cumulative=T, mode="all")
plot( x=0:max(degree(net)), y=1-deg.dist, pch=19, cex=1.4, col="orange",
xlab="Degree", ylab="Cumulative Frequency")
交互網(wǎng)絡(luò)
如果你已經(jīng)安裝了“ndtv”括改,你還應(yīng)該有一個(gè)它使用的名為“animation”的包腻豌。如果沒有,現(xiàn)在是時(shí)候用install.packages('animation')來安裝它了嘱能。注意吝梅,這個(gè)包提供了一種簡單的技術(shù)來在r中創(chuàng)建各種(不一定是與網(wǎng)絡(luò)相關(guān)的)動(dòng)畫。它通過生成多個(gè)情節(jié)并將它們組合到一個(gè)GIF動(dòng)畫中工作惹骂。
這里的問題是苏携,為了使其工作,您不僅需要R包对粪,還需要一個(gè)名為ImageMagick的附加軟件(imagemagick.org)右冻。您可能不想在研討會(huì)期間安裝它,但您可以在家里嘗試著拭。
好消息是纱扭,一旦您明白了這一點(diǎn),您就可以將任何系列的R圖形(網(wǎng)絡(luò)或非網(wǎng)絡(luò)!)轉(zhuǎn)換為GIF動(dòng)畫茫死。
library("animation")
library("igraph")
# In order for this to work, you need not only the R package, but also
# an additional software called ImageMagick from imagemagick.org
# If you don't already have it, skip this part of the tutorial for now.
ani.options("convert") # Check that the package knows where to find ImageMagick
ani.options(convert="C:/Progra~1/ImageMagick-7.0.6-Q16/convert.exe")
# You can use this technique to create various (not necessarily network-related)
# animations in R by generating multiple plots and combining them in an animated GIF.
l <- layout_with_lgl(net)
saveGIF( { col <- rep("grey40", vcount(net))
plot(net, vertex.color=col, layout=l)
step.1 <- V(net)[media=="Wall Street Journal"]
col[step.1] <- "#ff5100"
plot(net, vertex.color=col, layout=l)
step.2 <- unlist(neighborhood(net, 1, step.1, mode="out"))
col[setdiff(step.2, step.1)] <- "#ff9d00"
plot(net, vertex.color=col, layout=l)
step.3 <- unlist(neighborhood(net, 2, step.1, mode="out"))
col[setdiff(step.3, step.2)] <- "#FFDD1F"
plot(net, vertex.color=col, layout=l) },
interval = .8, movie.name="network_animation.gif" )
detach("package:igraph")
detach("package:animation")
交互式JS可視化與visNetwork
現(xiàn)在跪但,將R圖導(dǎo)出到HTML/JavaScript輸出相當(dāng)容易。有許多像rcharts和htmlwidgets這樣的包可以幫助您直接從r創(chuàng)建交互式web圖表峦萎。但是有一點(diǎn)需要記住的是屡久,以這種方式創(chuàng)建的網(wǎng)絡(luò)可視化作為進(jìn)一步工作的起點(diǎn)是非常有用的。如果您了解一點(diǎn)javascript爱榔,那么您可以將其作為第一步來使用被环,并調(diào)整結(jié)果以更接近您想要的結(jié)果。
這里我們將快速瀏覽一下visNetwork详幽,它使用vis.js javascript庫生成交互式網(wǎng)絡(luò)可視化筛欢。你可以用install.packages('visNetwork')來安裝這個(gè)包浸锨。
我們可以馬上可視化我們的媒體網(wǎng)絡(luò):visNetwork()將接受我們的節(jié)點(diǎn)和鏈接數(shù)據(jù)幀。通常版姑,節(jié)點(diǎn)數(shù)據(jù)框架需要有一個(gè)id列柱搜,而鏈接數(shù)據(jù)需要有表示每個(gè)綁定的開始和結(jié)束的from和to列。
library("visNetwork")
head(nodes)
head(links)
# We can visualize the network right away - visNetwork() will accept
# our node and link data frames (it needs node data with an 'id' column,
# and edge data with 'from' and 'to' columns).
visNetwork(nodes, links)
# We can set the height and width of the visNetwork() window
# with parameters 'height' and 'width', the back color with 'background',
# the title, subtitle, and footer with 'main', 'submain', and 'footer'
visNetwork(nodes, links, height="600px", width="100%", background="#eeefff",
main="Network", submain="And what a great network it is!",
footer= "Hyperlinks and mentions among media sources")
在下面的代碼中剥险,我們將更改一些節(jié)點(diǎn)的可視參數(shù)聪蘸。我們從節(jié)點(diǎn)形狀開始(它的可用選項(xiàng)包括橢圓、圓表制、數(shù)據(jù)庫健爬、框、文本么介、圖像娜遵、圓圖像、菱形壤短、點(diǎn)设拟、星形、三角形鸽扁、三角向下蒜绽、正方形和圖標(biāo))。我們還將更改幾個(gè)節(jié)點(diǎn)元素的顏色桶现。在這個(gè)包中躲雅,背景控制節(jié)點(diǎn)的顏色,邊框改變幀的顏色;高亮設(shè)置鼠標(biāo)點(diǎn)擊時(shí)的顏色骡和,懸停設(shè)置鼠標(biāo)越過時(shí)的顏色相赁。
# We'll start by adding new node and edge attributes to our dataframes.
vis.nodes <- nodes
vis.links <- links
# The options for node shape include 'ellipse', 'circle',
# 'database', 'box', 'text', 'image', 'circularImage', 'diamond',
# 'dot', 'star', 'triangle', 'triangleDown', 'square', and 'icon'
vis.nodes$shape <- "dot"
vis.nodes$shadow <- TRUE # Nodes will drop shadow
vis.nodes$title <- vis.nodes$media # Text on click
vis.nodes$label <- vis.nodes$type.label # Node label
vis.nodes$size <- vis.nodes$audience.size # Node size
vis.nodes$borderWidth <- 2 # Node border width
# We can set the color for several elements of the nodes:
# "background" changes the node color, "border" changes the frame color;
# "highlight" sets the color on click, "hover" sets the color on mouseover.
vis.nodes$color.background <- c("slategrey", "tomato", "gold")[nodes$media.type]
vis.nodes$color.border <- "black"
vis.nodes$color.highlight.background <- "orange"
vis.nodes$color.highlight.border <- "darkred"
visNetwork(vis.nodes, vis.links)
# Below we change some of the visual properties of the edges:
vis.links$width <- 1+links$weight/8 # line width
vis.links$color <- "gray" # line color
vis.links$arrows <- "middle" # arrows: 'from', 'to', or 'middle'
vis.links$smooth <- FALSE # should the edges be curved?
vis.links$shadow <- FALSE # edge shadow
visNetwork(vis.nodes, vis.links)
vis.links$arrows <- ""
vis.links$width <- 1
visnet <- visNetwork(vis.nodes, vis.links)
visnet
# We can also set the visualization options directly with visNodes() and visEdges()
visnet2 <- visNetwork(nodes, links)
visnet2 <- visNodes(visnet2, shape = "square", shadow = TRUE,
color=list(background="gray", highlight="orange", border="black"))
visnet2 <- visEdges(visnet2, color=list(color="black", highlight = "orange"),
smooth = FALSE, width=2, dashes= TRUE, arrows = 'middle' )
visnet2
visNetwork在visOptions()函數(shù)中提供了許多其他選項(xiàng)。例如慰于,我們可以突出顯示所選節(jié)點(diǎn)的所有鄰居(highlightNearest)钮科,或者添加一個(gè)下拉菜單來選擇節(jié)點(diǎn)子集(selectedBy)。子集基于數(shù)據(jù)中的一列—這里我們使用類型標(biāo)簽婆赠。
visOptions(visnet, highlightNearest = TRUE, selectedBy = "type.label")
visNetwork還可以使用預(yù)定義的節(jié)點(diǎn)組绵脯。可以使用visGroups()設(shè)置屬于每個(gè)組的節(jié)點(diǎn)的視覺特征休里。我們可以使用visLegend()添加一個(gè)自動(dòng)生成的組圖例蛆挫。
nodes$group <- nodes$type.label
visnet3 <- visNetwork(nodes, links)
visnet3 <- visGroups(visnet3, groupname = "Newspaper", shape = "square",
color = list(background = "gray", border="black"))
visnet3 <- visGroups(visnet3, groupname = "TV", shape = "dot",
color = list(background = "tomato", border="black"))
visnet3 <- visGroups(visnet3, groupname = "Online", shape = "diamond",
color = list(background = "orange", border="black"))
visLegend(visnet3, main="Legend", position="right", ncol=1)
threejs
另一個(gè)將網(wǎng)絡(luò)從R導(dǎo)出到j(luò)avascript的好包是threejs,它使用three.js javascript庫和htmlwidgets R包生成交互式網(wǎng)絡(luò)可視化妙黍。關(guān)于threejs的一個(gè)優(yōu)點(diǎn)是它可以直接讀取igraph對象悴侵。
# install.packages('threejs')
library(threejs)
library(htmlwidgets)
library(igraph)
這里的主要網(wǎng)絡(luò)繪圖函數(shù)graphjs將接受一個(gè)igraph對象。我們可以對初始的net對象稍加修改:我們將刪除它的圖形布局拭嫁,讓三個(gè)ejb自己生成一個(gè)可免。我們在前面做了一點(diǎn)小弊抓于,給igraph對象中的布局屬性分配了一個(gè)函數(shù),而不是給它一個(gè)節(jié)點(diǎn)坐標(biāo)表浇借。這在igraph上是可以的捉撮,但是threejs不讓我們這么做。
net.js <- net
graph_attr(net.js, "layout") <- NULL
gjs <- graphjs(net.js, main="Network!", bg="gray10", showLabels=F, stroke=F,
curvature=0.1, attraction=0.9, repulsion=0.8, opacity=0.9)
print(gjs)
saveWidget(gjs, file="Media-Network-gjs.html")
browseURL("Media-Network-gjs.html")
一旦我們在瀏覽器中打開結(jié)果可視化逮刨,我們就可以使用鼠標(biāo)滾動(dòng)輪來放大和縮小呕缭,鼠標(biāo)左鍵來旋轉(zhuǎn)網(wǎng)絡(luò)堵泽,鼠標(biāo)右鍵來平移修己。
我們還可以通過使用布局、頂點(diǎn)顏色和邊顏色列表來創(chuàng)建簡單的動(dòng)畫迎罗,這些列表在每一步都會(huì)切換睬愤。
gjs.an <- graphjs(net.js, bg="gray10", showLabels=F, stroke=F,
layout=list(layout_randomly(net.js, dim=3),
layout_with_fr(net.js, dim=3),
layout_with_drl(net.js, dim=3),
layout_on_sphere(net.js)),
vertex.color=list(V(net.js)$color, "gray", "orange", V(net.js)$color),
main=list("Random Layout", "Fruchterman-Reingold", "DrL layout", "Sphere" ) )
print(gjs.an)
saveWidget(gjs.an, file="Media-Network-gjs-an.html")
browseURL("Media-Network-gjs-an.html")
networkD3
我們還將快速瀏覽一下networkD3,正如它的名字所暗示的那樣纹安,它使用D3 javascript庫生成交互式網(wǎng)絡(luò)可視化尤辱。如果你沒有networkD3庫,用install.packages(“networkD3”)安裝它厢岂。
這個(gè)庫需要從is得到的數(shù)據(jù)是標(biāo)準(zhǔn)的邊緣列表形式光督,稍微做了一些改動(dòng)。為了讓事情正常運(yùn)行塔粒,節(jié)點(diǎn)id必須是數(shù)字结借,而且它們也必須從0開始。一種簡單的方法是將字符id轉(zhuǎn)換為因子變量卒茬,再將其轉(zhuǎn)換為數(shù)值船老,并確保它從0開始減去1。
#install.packages("networkD3")
library(networkD3)
# d3ForceNetwork expects node IDs that are numeric and start from 0
# so we have to transform our character node IDs:
links.d3 <- data.frame(from=as.numeric(factor(links$from))-1,
to=as.numeric(factor(links$to))-1 )
# The nodes need to be in the same order as the "source" column in links:
nodes.d3 <- cbind(idn=factor(nodes$media, levels=nodes$media), nodes)
# The `Group` parameter is used to color the nodes.
# Nodesize is not (as you might think) the size of the node, but the
# number of the column in the node data that should be used for sizing.
# The `charge` parameter guides node repulsion (if negative) or
# attraction (if positive).
forceNetwork(Links = links.d3, Nodes = nodes.d3, Source="from", Target="to",
NodeID = "idn", Group = "type.label",linkWidth = 1,
linkColour = "#afafaf", fontSize=12, zoom=T, legend=T,
Nodesize=6, opacity = 1, charge=-600,
width = 600, height = 600)
使用ndtv-d3實(shí)現(xiàn)動(dòng)態(tài)網(wǎng)絡(luò)可視化
在這里圃酵,我們將使用ndtv包創(chuàng)建D3可視化柳畔。你不需要額外的軟件來用ndtv制作網(wǎng)頁動(dòng)畫。如果您想將動(dòng)畫保存為視頻文件(參見saveVideo)郭赐,則必須安裝名為FFmpeg的視頻轉(zhuǎn)換器(http://ffmpg.org)薪韩。要了解如何為你的操作系統(tǒng)進(jìn)行正確的安裝,請查看?install.ffmpeg捌锭。要使用所有可用的布局俘陷,您還需要在您的機(jī)器上安裝Java。
下面的大多數(shù)參數(shù)在這一點(diǎn)上是不言自明的(bg是圖的背景色)舀锨。兩個(gè)我們以前沒有使用過的新參數(shù)是vertex岭洲。工具提示和edge.tooltip。這些包含我們在將鼠標(biāo)移動(dòng)到網(wǎng)絡(luò)元素上時(shí)可以看到的信息坎匿。注意盾剩,工具提示參數(shù)接受html標(biāo)記——例如雷激,我們將使用換行標(biāo)記
。參數(shù)launchBrowser指示R在瀏覽器中打開生成的可視化文件(文件名)告私。
# install.packages('ndtv', dependencies=T)
library('ndtv')
net3
par(mar=c(0,0,0,0))
render.d3movie(net3, usearrows = F, displaylabels = F, bg="#111111",
vertex.border="#ffffff", vertex.col = net3 %v% "col",
vertex.cex = (net3 %v% "audience.size")/8,
edge.lwd = (net3 %e% "weight")/3, edge.col = '#55555599',
vertex.tooltip = paste("<b>Name:</b>", (net3 %v% 'media') , "<br>",
"<b>Type:</b>", (net3 %v% 'type.label')),
edge.tooltip = paste("<b>Edge type:</b>", (net3 %e% 'type'), "<br>",
"<b>Edge weight:</b>", (net3 %e% "weight" ) ),
launchBrowser=F, filename="Media-Network.html" )
文章的后面是幾個(gè)交互的例子屎暇,交互的程度越高,對設(shè)備的要求也越高驻粟。那么根悼,網(wǎng)絡(luò)可視化的為未來是交互嗎?
在地理地圖上覆蓋網(wǎng)絡(luò)
本節(jié)中展示的示例僅使用基本R和映射包蜀撑。如果您有使用ggplot2的經(jīng)驗(yàn)挤巡,那么該包確實(shí)提供了一種更通用的方法來完成此任務(wù)。使用ggplot()的代碼與您將在下面看到的代碼類似酷麦,但是您將使用borders()繪制地圖矿卑,使用geom_path()繪制邊緣。
為了在地圖上繪制沃饶,我們還需要一些包裝母廷。正如您將在下面看到的,maps將讓我們生成一個(gè)地理地圖來用作背景糊肤,geosphere將讓我們生成表示網(wǎng)絡(luò)邊緣的弧線琴昆。如果您還沒有它們,請安裝這兩個(gè)包馆揉,然后加載它們业舍。
#install.packages("maps")
#install.packages("geosphere")
library("maps")
library("geosphere")
# Package 'maps' has built-in maps it can plot for you. For example:
# ('col' is map fill, 'border' is border color, 'bg' is background color)
par(mfrow = c(2,2))
map("usa", col="tomato", border="gray10", fill=TRUE, bg="gray30")
map("state", col="orange", border="gray10", fill=TRUE, bg="gray30")
map("county", col="palegreen", border="gray10", fill=TRUE, bg="gray30")
map("world", col="skyblue", border="gray10", fill=TRUE, bg="gray30")
我們將在這里使用的數(shù)據(jù)包含美國機(jī)場和它們之間的航班。機(jī)場文件包括地理坐標(biāo)——經(jīng)緯度把介。如果您的數(shù)據(jù)中沒有這些勤讽,您可以使用包ggmap中的geocode()函數(shù)獲取地址的緯度和經(jīng)度。
airports <- read.csv("./Data Files/Dataset3-Airlines-NODES.csv", header=TRUE)
flights <- read.csv("./Data Files/Dataset3-Airlines-EDGES.csv", header=TRUE, as.is=TRUE)
head(flights)
Source Target Freq
1 0 109 10
2 1 36 10
3 1 61 10
4 2 152 10
5 3 104 10
6 4 132 10
> head(airports)
ID Label Code City latitude longitude
1 0 Adams Field Airport LIT Little Rock, AR 34.72944 -92.22444
2 1 Akron/canton Regional CAK Akron/Canton, OH 40.91611 -81.44222
3 2 Albany International ALB Albany 42.73333 -73.80000
4 3 Albemarle CHO Charlottesville 38.13333 -78.45000
5 4 Albuquerque International ABQ Albuquerque 35.04028 -106.60917
6 5 Alexandria International AEX Alexandria, LA 31.32750 -92.54861
ToFly Visits
1 0 105
2 0 123
3 0 129
4 1 114
5 0 105
6 0 93
# Select only large airports: ones with more than 10 connections in the data.
tab <- table(flights$Source)
big.id <- names(tab)[tab>10]
airports <- airports[airports$ID %in% big.id,]
flights <- flights[flights$Source %in% big.id &
flights$Target %in% big.id, ]
# Plot a map of the united states:
map("state", col="grey20", fill=TRUE, bg="black", lwd=0.1)
# Add a point on the map for each airport:
points(x=airports$longitude, y=airports$latitude, pch=19,
cex=airports$Visits/80, col="orange")
# Generate edge colors: lighter color means higher flight volume.
col.1 <- adjustcolor("orange red", alpha=0.4)
col.2 <- adjustcolor("orange", alpha=0.4)
edge.pal <- colorRampPalette(c(col.1, col.2), alpha = TRUE)
edge.col <- edge.pal(100)
# For each flight, we will generate the coordinates of an arc that connects
# its star and end point, using gcIntermediate() from package 'geosphere'.
# Then we will plot that arc over the map using lines().
for(i in 1:nrow(flights)) {
node1 <- airports[airports$ID == flights[i,]$Source,]
node2 <- airports[airports$ID == flights[i,]$Target,]
arc <- gcIntermediate( c(node1[1,]$longitude, node1[1,]$latitude),
c(node2[1,]$longitude, node2[1,]$latitude),
n=1000, addStartEnd=TRUE )
edge.ind <- round(100*flights[i,]$Freq / max(flights$Freq))
lines(arc, col=edge.col[edge.ind], lwd=edge.ind/30)
}