R語言繪圖包13--共表達(dá)網(wǎng)絡(luò)的繪制:igraph


R語言繪圖包系列:


網(wǎng)絡(luò)圖飒箭,是一種包含了節(jié)點(diǎn)V(即網(wǎng)絡(luò)參與者案淋,也稱頂點(diǎn))與邊E(即節(jié)點(diǎn)之間的連接關(guān)系)的數(shù)學(xué)結(jié)構(gòu)琅拌,記作G={V,E}辜腺¢暇担可以使用一個(gè)矩陣來存放節(jié)點(diǎn)之間的連接關(guān)系个榕,這個(gè)矩陣稱為鄰接矩陣鸵赖。如果網(wǎng)絡(luò)中兩個(gè)節(jié)點(diǎn)之間的邊是有方向的抚恒,即從節(jié)點(diǎn)u出發(fā)指向節(jié)點(diǎn)v,這就是一個(gè)有向網(wǎng)絡(luò)(有向圖)巡蘸,否則稱為無向網(wǎng)絡(luò)(無向圖)奋隶。網(wǎng)絡(luò)的邊也可以賦予權(quán)重,稱為加權(quán)網(wǎng)絡(luò)悦荒。

1. igraph繪圖

1.1 基礎(chǔ)繪圖
###安裝并載入演示數(shù)據(jù)集
library(devtools)
install_github("kassambara/navdata")
library("navdata")
###載入數(shù)據(jù)集
data("phone.call") #示例集來自于navdata包(是一個(gè)假想的數(shù)據(jù)集唯欣,里邊有一個(gè)不存在的國家Slovania)
這個(gè)數(shù)據(jù)集表示的是在某段時(shí)間內(nèi)歐洲部分國家領(lǐng)導(dǎo)人之間的通話次數(shù)。由數(shù)據(jù)可見搬味,這是一個(gè)由source指向destination境氢,以通話次數(shù)為權(quán)重的有向加權(quán)網(wǎng)絡(luò)。

igraph有特定的網(wǎng)絡(luò)(圖)對象類“igraph”碰纬。建立一個(gè)圖的最簡單的方法是用函數(shù)graph.formula()手工輸入節(jié)點(diǎn)的對應(yīng)關(guān)系萍聊,考慮到實(shí)際上的網(wǎng)絡(luò)規(guī)模都是比較大的,我們幾乎不會(huì)用到這種方法悦析。更常用的方式有兩種:

  • 從數(shù)據(jù)框(節(jié)點(diǎn)列表和邊列表)建立網(wǎng)絡(luò)對象

這種方法需要我們先建立兩個(gè)數(shù)據(jù)框:
邊列表:包含節(jié)點(diǎn)標(biāo)簽和節(jié)點(diǎn)的其他屬性
節(jié)點(diǎn)列表:包含節(jié)點(diǎn)之間聯(lián)系(也就是邊)和邊的屬性
此時(shí)寿桨,可以使用graph_from_data_frame()建立igraph對象。

  • 從鄰接矩陣建立網(wǎng)絡(luò)對象

如果數(shù)據(jù)集是表示節(jié)點(diǎn)連接關(guān)系的矩陣形式(比如說就像相關(guān)系數(shù)矩陣那樣)强戴,可以使用graph_from_adjacency_matrix()建立igraph對象
對于phone.call這個(gè)數(shù)據(jù)集亭螟,要?jiǎng)?chuàng)建節(jié)點(diǎn)列表,需要將source和destination這兩列包含的各個(gè)國家的名稱提取出來骑歹,即提取獨(dú)特的行觀測预烙,這使用dplyr包的distinct函數(shù)來實(shí)現(xiàn)。然后道媚,我們創(chuàng)建一個(gè)新變量location扁掸,表示這些節(jié)點(diǎn)的地理位置:

library(tidyverse)
name<-data.frame(c(phone.call$source,phone.call$destination))
nodes<-name%>%
    distinct()%>%
mutate(location=c("western","western","central","nordic","southeastern",
     "southeastern","southeastern","southern","sourthern",
     "western","western","central","central","central","central","central"))
colnames(nodes)<-c("label","location")

下面來看邊列表。數(shù)據(jù)集phone.call的前兩列分別表示了邊出發(fā)和終結(jié)的節(jié)點(diǎn)最域。所以這個(gè)數(shù)據(jù)集就是邊列表的形式谴分,第三列n.call可以作為邊的權(quán)重。我們把這些列的名稱改成更直觀的名字:

edges<-phone.call%>%rename(from=source,to=destination,weight=n.call)

現(xiàn)在可以創(chuàng)建一個(gè)igraph對象了:

library(igraph)

net_pc<-graph_from_data_frame(
   d=edges,vertices=nodes,
   directed=TRUE)

net_pc

可以看到輸出的igraph對象:

3f802ae是這個(gè)對象的名稱羡宙,DNW- 16 18 --表示這是一個(gè)有向(D)狸剃、有命名(N)且加權(quán)(W)的網(wǎng)絡(luò),它有16個(gè)節(jié)點(diǎn)和18條邊狗热。它具有的節(jié)點(diǎn)屬性是name , location 钞馁,具有的邊屬性是weight。

我們可以通過V()和E()對節(jié)點(diǎn)和邊的屬性進(jìn)行訪問匿刮,如:

V(net_pc)
# + 16/16 vertices, named, from 3f802ae:
#  [1] France         Belgium        Germany        Danemark      
#  [5] Croatia        Slovenia       Hungary        Spain         
#  [9] Italy          Netherlands    UK             Austria       
# [13] Poland         Switzerland    Czech republic Slovania     
V(net_pc)$location 
# [1] "western"      "western"      "central"      "nordic"      
#  [5] "southeastern" "southeastern" "southeastern" "southern"    
#  [9] "sourthern"    "western"      "western"      "central"     
# [13] "central"      "central"      "central"      "central"     

這種方法也可以用于指定或修正相應(yīng)的節(jié)點(diǎn)和邊的屬性僧凰,這在igraph可視化中是很常用的。

還可以從net_pc這個(gè)網(wǎng)絡(luò)中提取邊列表或者鄰接矩陣:

###提取邊列表
as_edgelist(net_pc, names=T) 
      [,1]       [,2]            
#  [1,] "France"   "Germany"       
#  [2,] "Belgium"  "France"        
#  [3,] "France"   "Spain"         
#  [4,] "France"   "Italy"         
#  [5,] "France"   "Netherlands"   
#  [6,] "France"   "UK"            
#  [7,] "Germany"  "Austria"       
#  [8,] "Germany"  "Poland"        
#  [9,] "Belgium"  "Germany"       
# [10,] "Germany"  "Switzerland"   
# [11,] "Germany"  "Czech republic"
# [12,] "Germany"  "Netherlands"   
# [13,] "Danemark" "Germany"       
# [14,] "Croatia"  "Germany"       
# [15,] "Croatia"  "Slovania"      
# [16,] "Croatia"  "Hungary"       
# [17,] "Slovenia" "Germany"       
# [18,] "Hungary"  "Slovania"     
###提取鄰接矩陣
as_adjacency_matrix(net_pc, attr="weight")
# 16 x 16 sparse Matrix of class "dgCMatrix"
#   [[ suppressing 16 column names ‘France’, ‘Belgium’, ‘Germany’ ... ]]
                                                
# France         . . 9 . . . . 3 4 2 3 . . . . .  
# Belgium        4 . 3 . . . . . . . . . . . . .  
# Germany        . . . . . . . . . 2 . 2 2 2 2 .  
# Danemark       . . 2 . . . . . . . . . . . . .  
# Croatia        . . 2 . . . 2 . . . . . . . . 2.0
# Slovenia       . . 2 . . . . . . . . . . . . .  
# Hungary        . . . . . . . . . . . . . . . 2.5
# Spain          . . . . . . . . . . . . . . . .  
# Italy          . . . . . . . . . . . . . . . .  
# Netherlands    . . . . . . . . . . . . . . . .  
# UK             . . . . . . . . . . . . . . . .  
# Austria        . . . . . . . . . . . . . . . .  
# Poland         . . . . . . . . . . . . . . . .  
# Switzerland    . . . . . . . . . . . . . . . .  
# Czech republic . . . . . . . . . . . . . . . .  
# Slovania       . . . . . . . . . . . . . . . .  

現(xiàn)在可以看一下這個(gè)網(wǎng)絡(luò)了(圖3):

plot(net_pc)
1.2 可視化基礎(chǔ)

igraph的plot函數(shù)中提供了大量的參數(shù)用于展示節(jié)點(diǎn)熟丸、邊以及圖形的各種屬性训措,其中涉及節(jié)點(diǎn)的參數(shù)是以vertex.開頭的,涉及邊的參數(shù)是以edge.開頭的。

除了在plot()中指定節(jié)點(diǎn)和邊的參數(shù)之外绩鸣,還可以使用前面提到的V()E()怀大,直接在igraph對象中添加相應(yīng)的屬性。這兩種方法的區(qū)別在于呀闻,在plot()中指定的參數(shù)并不會(huì)改變圖的屬性化借。比如,我們先按照位置指定節(jié)點(diǎn)的顏色捡多,按照權(quán)重指定邊的寬度(這兩個(gè)屬性會(huì)保存在net_pc對象中)蓖康,然后在plot()的參數(shù)中指定節(jié)點(diǎn)的大小(與節(jié)點(diǎn)的度成比例垒手,節(jié)點(diǎn)度是與這個(gè)節(jié)點(diǎn)相連的邊的個(gè)數(shù))蒜焊、節(jié)點(diǎn)標(biāo)記的大小和位置、邊的顏色科贬、箭頭的大小和邊的彎曲程度

###計(jì)算節(jié)點(diǎn)的度
deg<-degree(net_pc,mode="all")
###設(shè)置顏色
vcolor<-c("orange","red","lightblue","tomato","yellow")
###指定節(jié)點(diǎn)的顏色
V(net_pc)$color<-vcolor[factor(V(net_pc)$location)]
###指定邊的顏色
E(net_pc)$width<-E(net_pc)$weight/2

plot(net_pc,vertex.size=3*deg,
vertex.label.cex=.7,vertex.label.dist=1,
edge.color="gray50",edge.arrow.size=.4, edge.curved=.1)
###添加圖例
legend(x=1.5,y=1.5,levels(factor(V(net_pc)$location)),pch=21,col="#777777",pt.bg=vcolor)
1.3 網(wǎng)絡(luò)布局

網(wǎng)絡(luò)布局指的是確定網(wǎng)絡(luò)中每個(gè)節(jié)點(diǎn)坐標(biāo)的方法泳梆。

igraph中提供了多種布局算法,其中最有用的是幾種力導(dǎo)向(Force-directed)布局算法唆迁。力導(dǎo)向布局試圖得到一個(gè)美觀的圖形鸭丛,其中的邊在長度上相似,并且盡可能少地交叉唐责。它們把圖形模擬成一個(gè)物理系統(tǒng)鳞溉。節(jié)點(diǎn)是帶電粒子,當(dāng)它們靠得太近時(shí)會(huì)互相排斥鼠哥。這些邊充當(dāng)彈簧熟菲,將連接的節(jié)點(diǎn)吸引在一起。結(jié)果朴恳,節(jié)點(diǎn)在圖示區(qū)域中均勻分布抄罕,并且布局直觀,因?yàn)楣蚕砀噙B接的節(jié)點(diǎn)彼此更接近于颖。這些算法的缺點(diǎn)是速度很慢呆贿,因此在大于1000個(gè)頂點(diǎn)的圖中使用的頻率較低。

使用力導(dǎo)向布局時(shí)森渐,可以使用niter參數(shù)控制要執(zhí)行的迭代次數(shù)做入。默認(rèn)設(shè)置為500次迭代。對于大型的圖同衣,可以降低該數(shù)字以更快地獲得結(jié)果竟块,并檢查它們是否合理。

Fruchterman-Reingold是最常用的力導(dǎo)向布局算法:

l <- layout_with_fr(net_pc) 
plot(net_pc, layout=l)

Fruchterman Reingold布局具有隨機(jī)性耐齐,不同的運(yùn)行將導(dǎo)致略有不同的布局配置浪秘。將布局保存在對象l當(dāng)中蒋情,可以使我們多次獲得完全相同的結(jié)果(也可以實(shí)現(xiàn)指定隨機(jī)數(shù)種子seed())。

我們通過一張圖來展示所有的(用于單模圖的)布局方式:

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(5,3), mar=c(1,1,1,1)) 
for (layout in layouts) {
print(layout)
l <- do.call(layout, list(net_pc))
plot(net_pc, vertex.label="",edge.arrow.mode=0, layout=l, main=layout) }

參考:R語言網(wǎng)絡(luò)數(shù)據(jù)可視化(1):igraph基礎(chǔ)

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
禁止轉(zhuǎn)載耸携,如需轉(zhuǎn)載請通過簡信或評論聯(lián)系作者棵癣。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市违帆,隨后出現(xiàn)的幾起案子浙巫,更是在濱河造成了極大的恐慌,老刑警劉巖刷后,帶你破解...
    沈念sama閱讀 206,013評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異渊抄,居然都是意外死亡尝胆,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,205評論 2 382
  • 文/潘曉璐 我一進(jìn)店門护桦,熙熙樓的掌柜王于貴愁眉苦臉地迎上來含衔,“玉大人,你說我怎么就攤上這事二庵√叭荆” “怎么了?”我有些...
    開封第一講書人閱讀 152,370評論 0 342
  • 文/不壞的土叔 我叫張陵催享,是天一觀的道長杭隙。 經(jīng)常有香客問我,道長因妙,這世上最難降的妖魔是什么痰憎? 我笑而不...
    開封第一講書人閱讀 55,168評論 1 278
  • 正文 為了忘掉前任,我火速辦了婚禮攀涵,結(jié)果婚禮上铣耘,老公的妹妹穿的比我還像新娘。我一直安慰自己以故,他們只是感情好蜗细,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,153評論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著怒详,像睡著了一般炉媒。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上棘利,一...
    開封第一講書人閱讀 48,954評論 1 283
  • 那天橱野,我揣著相機(jī)與錄音,去河邊找鬼善玫。 笑死水援,一個(gè)胖子當(dāng)著我的面吹牛密强,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播蜗元,決...
    沈念sama閱讀 38,271評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼或渤,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了奕扣?” 一聲冷哼從身側(cè)響起薪鹦,我...
    開封第一講書人閱讀 36,916評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎惯豆,沒想到半個(gè)月后池磁,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,382評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡楷兽,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,877評論 2 323
  • 正文 我和宋清朗相戀三年地熄,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片芯杀。...
    茶點(diǎn)故事閱讀 37,989評論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡端考,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出揭厚,到底是詐尸還是另有隱情却特,我是刑警寧澤,帶...
    沈念sama閱讀 33,624評論 4 322
  • 正文 年R本政府宣布筛圆,位于F島的核電站裂明,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏顽染。R本人自食惡果不足惜漾岳,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,209評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望粉寞。 院中可真熱鬧尼荆,春花似錦、人聲如沸唧垦。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,199評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽振亮。三九已至巧还,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間坊秸,已是汗流浹背麸祷。 一陣腳步聲響...
    開封第一講書人閱讀 31,418評論 1 260
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留褒搔,地道東北人阶牍。 一個(gè)月前我還...
    沈念sama閱讀 45,401評論 2 352
  • 正文 我出身青樓喷面,卻偏偏與公主長得像,于是被迫代替她去往敵國和親走孽。 傳聞我的和親對象是個(gè)殘疾皇子惧辈,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,700評論 2 345

推薦閱讀更多精彩內(nèi)容