每次有正事的時(shí)候就想逃避寫個(gè)簡(jiǎn)書(shū)祥诽,假裝自己沒(méi)有干不正經(jīng)的事豆拨。(明明我還有一些數(shù)據(jù)需要分析呢痹束,但是毫無(wú)分析的動(dòng)力。)好的仓技,今天我們來(lái)介紹一個(gè)很酷炫的圖:弧形圖(Arc Diagram)鸵贬。
什么是弧形圖(Arc Diagram)
弧形圖顧名思義,是由弧形組成的脖捻。粗暴一點(diǎn)阔逼,直接上圖讓大家來(lái)看一下什么是弧形圖。
可以看到上圖中有很多個(gè)節(jié)點(diǎn)郭变,不同的節(jié)點(diǎn)之間用弧形進(jìn)行連接颜价。沒(méi)錯(cuò),弧形圖就是一種可以用來(lái)表示關(guān)聯(lián)诉濒,展示多個(gè)節(jié)點(diǎn)之間關(guān)系的一種圖周伦。
這種關(guān)聯(lián)可能有多種情況,最常見(jiàn)的可以用于展現(xiàn)相關(guān)性結(jié)果未荒,還可以用于展現(xiàn)不同字詞共同出現(xiàn)的頻率等等(比如上面這張圖就分析了雨果的名作《悲慘世界》中的人物出現(xiàn)情況)专挪。
通過(guò)線的粗細(xì)、顏色以及節(jié)點(diǎn)的各種屬性片排,你可以在圖中展現(xiàn)關(guān)聯(lián)各種特性寨腔,比如可以用線的粗細(xì)表示共現(xiàn)的頻率,用節(jié)點(diǎn)大小表示該詞匯出現(xiàn)的頻率率寡。
你可能會(huì)疑惑迫卢,我們已經(jīng)有很多種展現(xiàn)關(guān)聯(lián)的方式,比如最簡(jiǎn)單的網(wǎng)絡(luò)圖或者和弦圖(好像我都沒(méi)有講過(guò)冶共,糟糕乾蛤,我以后慢慢補(bǔ))。為什么要用弧形圖呢捅僵?其實(shí)家卖,這幾種展現(xiàn)網(wǎng)絡(luò)關(guān)系的圖各自特點(diǎn),下面我們來(lái)看一個(gè)非常有意思的例子庙楚,以展現(xiàn)弧形圖的優(yōu)勢(shì)(例子來(lái)源:data-to-viz網(wǎng)站)上荡。
首先來(lái)介紹一下繪圖的數(shù)據(jù)。在學(xué)術(shù)圈馒闷,不同實(shí)驗(yàn)室之間可能會(huì)有一些長(zhǎng)期合作的關(guān)系酪捡,因此某些作者可能常常會(huì)出現(xiàn)在同一篇文章里叁征。比如有一些老板之間可能是師徒,或者是從同一個(gè)實(shí)驗(yàn)室里出來(lái)沛善,所以會(huì)經(jīng)常合作航揉。
而這次例子的數(shù)據(jù)就是收集了許多文章和作者塞祈,通過(guò)不同的網(wǎng)絡(luò)圖來(lái)展示作者之間的關(guān)聯(lián):如果兩個(gè)作者出現(xiàn)在同一篇文章里金刁,那么就會(huì)用線將他們連接起來(lái)。
我們先來(lái)看一下最基礎(chǔ)的網(wǎng)絡(luò)圖的效果议薪∮嚷可以看到出現(xiàn)了多個(gè)模塊,體現(xiàn)出了一些人之間的關(guān)系可能更為親密斯议。但是一旦關(guān)系復(fù)雜起來(lái)产捞,比如最大的那個(gè)模塊,似乎很難清楚地標(biāo)注每一個(gè)節(jié)點(diǎn)是誰(shuí)哼御。即便標(biāo)注出來(lái)了坯临,也不便于你快速找到你關(guān)注的目標(biāo)。
那么有沒(méi)有什么方法可以顯示所有人的姓名呢恋昼?和弦圖怎么樣看靠?
雖然和弦圖能夠表示所有人的姓名,但是與網(wǎng)絡(luò)圖比起來(lái)液肌,似乎人與人之間的關(guān)系沒(méi)有那么直觀了挟炬,感覺(jué)這些線有點(diǎn)雜亂無(wú)章。
那么我們?cè)賮?lái)看看弧形圖的效果嗦哆,可以發(fā)現(xiàn)弧形圖不僅能夠很好地展現(xiàn)每一個(gè)人的姓名谤祖,也可以看到一些人之間存在緊密的關(guān)聯(lián),一些人之間的關(guān)聯(lián)很少或者根本沒(méi)有關(guān)聯(lián)老速。
當(dāng)然粥喜,如果你對(duì)節(jié)點(diǎn)不進(jìn)行調(diào)整,那么就有可能出現(xiàn)下圖這種可怕的情況橘券。
不過(guò)如果能夠?qū)?jié)點(diǎn)的順序進(jìn)行一些調(diào)整额湘,和弦圖就能很好地體現(xiàn)出各個(gè)節(jié)點(diǎn)之間的關(guān)聯(lián),同時(shí)還能允許展現(xiàn)出每個(gè)節(jié)點(diǎn)的標(biāo)注约郁。而當(dāng)節(jié)點(diǎn)較多的時(shí)候缩挑,在網(wǎng)絡(luò)圖中其實(shí)很難做到這一點(diǎn),即便做到這一點(diǎn)鬓梅,也讓人覺(jué)得眼花繚亂供置。而和弦圖雖然也能展現(xiàn)出節(jié)點(diǎn)信息,但是由于是一個(gè)環(huán)狀绽快,所以也可讀性也不如弧形圖芥丧。
那么弧形圖要如何繪制呢紧阔?
怎么做弧形圖
1)需要什么格式的數(shù)據(jù)
我們還是用上面例子中的數(shù)據(jù),代碼來(lái)源還是參考上面提到的data-to-viz網(wǎng)站续担。
具體需要兩部分的數(shù)據(jù)擅耽,一部分是具體的貢獻(xiàn)情況connect表,另一個(gè)是各個(gè)作者的共現(xiàn)數(shù)目coauth表物遇。
library(tidyverse)
dataUU <- read.table("https://raw.githubusercontent.com/holtzy/data_to_viz/master/Example_dataset/13_AdjacencyUndirectedUnweighted.csv", header=TRUE)
#將dataUU轉(zhuǎn)化成所需的格式
connect <- dataUU %>%
gather(key="to", value="value", -1) %>% #將matrix變成三列乖仇,一列from,一列to询兴,一列共現(xiàn)文獻(xiàn)數(shù)
mutate(to = gsub("\\.", " ",to)) %>% #將to這一列中姓名.去掉變成空格
na.omit() #剔除NA
head(connect)#第一列的數(shù)字是剔除NA之前的行號(hào)
from to value
89 RF Murphy A Bateman 1
184 M Ardisson A Besnard 1
234 Y Holtz A Besnard 1
237 A Armero A Breil 1
276 FC Baurens A Breil 1
326 S Bocs A Breil 1
# 計(jì)算每個(gè)作者的共現(xiàn)條數(shù)
c( as.character(connect$from), as.character(connect$to)) %>%
as.tibble() %>% #將數(shù)據(jù)的type轉(zhuǎn)變?yōu)閠bl_df乃沙,tibble可以理解成是一種加強(qiáng)版的數(shù)據(jù)框
group_by(value) %>% #按照value進(jìn)行分組
summarize(n=n()) -> coauth
colnames(coauth) <- c("name", "n")#修改列名
head(coauth)
# A tibble: 6 x 2
value n
<chr> <int>
1 A Armero 6
2 A Bateman 5
3 A Besnard 6
4 A Breil 6
5 A Cenci 4
6 A Chifolleau 1
library(igraph)
mygraph <- graph_from_data_frame( connect, vertices = coauth, directed = FALSE )
理論上使用上述數(shù)據(jù)就可以作圖了(具體代碼參見(jiàn)下一小節(jié)),但是我們可以看一下做出來(lái)的效果诗舰。
沒(méi)錯(cuò)效果非常糟糕警儒,這就是我們?yōu)槭裁匆獙?duì)節(jié)點(diǎn)進(jìn)行調(diào)整的原因,那么我們要如何對(duì)節(jié)點(diǎn)進(jìn)行調(diào)整呢眶根?我們可以使用igraph包中的walktrap.community
函數(shù)蜀铲。這是一個(gè)用來(lái)進(jìn)行社區(qū)劃分的函數(shù)。
當(dāng)然属百,igraph包中還提供了許多其他劃分函數(shù)比如fastgreedy.community
记劝,spinglass.community
,edge.betweenness.community
,leading.eigenvector.community
等(不過(guò)我還沒(méi)有仔細(xì)研究過(guò)具體的區(qū)別)。
那么我們來(lái)調(diào)整一下數(shù)據(jù):
# 鑒定社區(qū)
com <- walktrap.community(mygraph)
#重新整理數(shù)據(jù)
coauth <- coauth %>%
mutate( grp = com$membership) %>%
arrange(grp) %>%
mutate(name=factor(name, name))
# 保留排名前15的社區(qū)
coauth <- coauth %>%
filter(grp<16)
# 只保留排名前15的社區(qū)涉及的作者
connect <- connect %>%
filter(from %in% coauth$name) %>%
filter(to %in% coauth$name)
mygraph <- graph_from_data_frame( connect, vertices = coauth, directed = FALSE )
2)如何作圖
接著诸老,我們將使用ggraph
函數(shù)進(jìn)行畫圖隆夯。
library(RColorBrewer)
library(ggraph)
mycolor<-colorRampPalette(brewer.pal(9, "Paired"))
ggraph(mygraph, layout="linear") +
geom_edge_arc(edge_colour="black", edge_alpha=0.2, edge_width=0.3, fold=TRUE) +
geom_node_point(aes(size=n, color=as.factor(grp), fill=grp), alpha=0.5) +
scale_size_continuous(range=c(0.5,8)) +
scale_color_manual(values=mycolor(15)) +
geom_node_text(aes(label=name), angle=65, hjust=1, nudge_y = -1.1, size=2.3) +
theme_void() +
theme(
legend.position="none",
plot.margin=unit(c(0,0,0.4,0), "null"),
panel.spacing=unit(c(0,0,3.4,0), "null")
) +
expand_limits(x = c(-1.2, 1.2), y = c(-5.6, 1.2))
今天的分享就到這里啦。
往期R數(shù)據(jù)可視化分享
R數(shù)據(jù)可視化17:杀鸱基圖
R數(shù)據(jù)可視化16:?jiǎn)♀張D
R數(shù)據(jù)可視化15:傾斜圖 Slope Graph
R數(shù)據(jù)可視化14:生存曲線圖
R數(shù)據(jù)可視化13:瀑布圖/突變圖譜
R數(shù)據(jù)可視化12: 曼哈頓圖
R數(shù)據(jù)可視化11: 相關(guān)性圖
R數(shù)據(jù)可視化10: 蜜蜂圖 Beeswarm
R數(shù)據(jù)可視化9: 棒棒糖圖 Lollipop Chart
R數(shù)據(jù)可視化8: 金字塔圖和偏差圖
R數(shù)據(jù)可視化7: 氣泡圖 Bubble Plot
R數(shù)據(jù)可視化6: 面積圖 Area Chart
R數(shù)據(jù)可視化5: 熱圖 Heatmap
R數(shù)據(jù)可視化4: PCA和PCoA圖
R數(shù)據(jù)可視化3: 直方/條形圖
R數(shù)據(jù)可視化2: 箱形圖 Boxplot
R數(shù)據(jù)可視化1: 火山圖