R語言繪圖包系列:
- R語言繪圖包01--優(yōu)秀的拼圖包patchwork
- R語言繪圖包02--熱圖pheatmap
- R語言繪圖包03--火山圖EnhancedVolcano
- R語言繪圖包04--GOplot:富集分析結(jié)果可視化
- R語言繪圖包05--韋恩圖的繪制:ggvenn和VennDiagram
- R語言繪圖包06--基因表達(dá)相關(guān)性繪圖corrplot
- R語言繪圖包07--多集合可視化UpSetR
- R語言繪圖包08--森林圖的繪制:forestplot
- R語言繪圖包09--序列分析圖的繪制ggseqlogo
- R語言繪圖包10--Circos圖的繪制:circlize包
- R語言繪圖包11--森林圖的繪制(2):forestploter包
- R語言繪圖包12--向日葵圖的繪制
網(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)
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) }