桑基圖,其實(shí)我用的不太多。最近常見(jiàn)還是在分析單細(xì)胞數(shù)據(jù)的時(shí)候,展示細(xì)胞通訊用的比較多的一種類型的圖。例如下面一張就是cellchat畫的一張?;鶊D。

x先看一下,百度對(duì)于桑基圖的定義。桑基圖(Sankey diagram),即?;芰糠至鲌D,也叫?;芰科胶鈭D。它是一種特定類型的流程圖,右圖中延伸的分支的寬度對(duì)應(yīng)數(shù)據(jù)流量的大小,通常應(yīng)用于能源、材料成分、金融等數(shù)據(jù)的可視化分析。因1898年Matthew Henry Phineas Riall Sankey繪制的“蒸汽機(jī)的能源效率圖”而聞名,此后便以其名字命名為“?;鶊D”。
所以從定義來(lái)看,一個(gè)簡(jiǎn)單的?;鶊D應(yīng)該具備,node和link。node分為source node和target node。而link衡量source node和target node之間的數(shù)據(jù)流量的大小。
library(networkD3)
library(ggplot2)
我們先來(lái)設(shè)置一個(gè)簡(jiǎn)單的node和link文件
nodes = data.frame("name" =
? ? ? ? ? ? ? ? ? ? c("Node A", # Node 0
? ? ? ? ? ? ? ? ? ? ? "Node B", # Node 1
? ? ? ? ? ? ? ? ? ? ? "Node C", # Node 2
? ? ? ? ? ? ? ? ? ? ? "Node D"))# Node 3
links = as.data.frame(matrix(c(
? 0, 1, 10, # Each row represents a link. The first number
? 0, 2, 20, # represents the node being conntected from.
? 1, 3, 30, # the second number represents the node connected to.
? 2, 3, 40),# The third number is the value of the node
? byrow = TRUE, ncol = 3))
names(links) = c("source", "target", "value")
從簡(jiǎn)單的測(cè)試數(shù)據(jù)來(lái)看,我們給定了4個(gè)node,并且設(shè)置了source node和target node之間的數(shù)據(jù)流動(dòng)情況。需要注意的是node是從0開(kāi)始計(jì)數(shù)的,這點(diǎn)和java一樣。

sankeyNetwork(Links = links, Nodes = nodes,Source = "source", Target = "target",Value = "value", NodeID = "name",fontSize= 12, nodeWidth = 30)
出來(lái)就是一個(gè)簡(jiǎn)單的桑基圖的樣子。value表示這些鏈接與之關(guān)聯(lián)的值,該值由鏈接的厚度表示。在示例中,連接節(jié)點(diǎn)A和節(jié)點(diǎn)B的第一條鏈接的寬度是連接A和C的第二條鏈接的寬度的一半。

這個(gè)函數(shù)的詳細(xì)參數(shù)解釋,大家也可以自己看下。Links指的就是我們輸入的node之間的links文件,Nodes文件就是node的指定文件。Source,Target,Value和NodeID指定source、target、value和name。

下面測(cè)試一下我們自己的數(shù)據(jù),先來(lái)一個(gè)簡(jiǎn)單點(diǎn)的。
這個(gè)是我們的第一個(gè)簡(jiǎn)單的測(cè)試數(shù)據(jù):

links <- read.csv("links.csv",header = T, fileEncoding = "UTF-8-BOM")
nodes <- read.csv("nodes.csv", header = T, fileEncoding = "UTF-8-BOM")
我們從csv文件讀入,后面fileEncoding主要是為了處理編碼問(wèn)題,有時(shí)候不知道為什么會(huì)出現(xiàn)亂碼,主要是中文等格式的問(wèn)題。
sankeyNetwork(Links = links, Nodes = nodes,
? ? ? ? ? ? ? Source = "source",
? ? ? ? ? ? ? Target = "target",
? ? ? ? ? ? ? Value = "value",
? ? ? ? ? ? ? NodeID = "name",
? ? ? ? ? ? ? fontSize = 12,
? ? ? ? ? ? ? nodeWidth = 30,
? ? ? ? ? ? ? nodePadding = 8
)
畫圖的函數(shù)和前面一樣。而 fontSize = 12, 表示節(jié)點(diǎn)的字體大小;nodeWidth = 30, 表示節(jié)點(diǎn)的寬度;nodePadding = 8 表示節(jié)點(diǎn)之間的距離。

換個(gè)稍微復(fù)雜點(diǎn)的數(shù)據(jù)集試下:


nodes <- read.csv("nodes1.csv",header = T, fileEncoding = "UTF-8-BOM")
links <- read.csv("links1.csv",header = T, fileEncoding = "UTF-8-BOM")
sn <- sankeyNetwork(Links = links, Nodes = nodes, Source = "source",
? ? ? ? ? ? ? Target = "target", Value = "value", NodeID = "name",
? ? ? ? ? ? ? units = "TWh", fontSize = 8, nodeWidth = 30)

也可以自己修改node或者link的顏色。
官網(wǎng)是這樣說(shuō)的:You can use this information to create a JavaScript color attribution object and call it using the?Nodegroup?argument.
就是我們可以自己創(chuàng)建一個(gè)javascript的顏色,好像java寫的包,還真是麻煩。
my_color <- 'd3.scaleOrdinal() .domain(["c1", "c2","c3"]) .range(["red", "steelblue","green"])'? ?//我們根據(jù)每個(gè)node的group來(lái)指定顏色。
sankeyNetwork(Links = links, Nodes = nodes, Source = "source",
? ? ? ? ? ? ? Target = "target", Value = "value", NodeID = "name",
? ? ? ? ? ? ? units = "TWh", fontSize = 8, nodeWidth = 30, colourScale=my_color, NodeGroup="group")

感覺(jué)這個(gè)包顏色設(shè)置不太方面。
可以根據(jù)link的分類來(lái)分別設(shè)置顏色。
my_color <- 'd3.scaleOrdinal() .domain(["c1", "c2","c3","type_a","type_b","type_c","type_d"]) .range(["red", "blue","green","#69b3a2", "steelblue", "grey","cyan"])'
sankeyNetwork(Links = links, Nodes = nodes, Source = "source",
? ? ? ? ? ? ? Target = "target", Value = "value", NodeID = "name",
? ? ? ? ? ? ? units = "TWh", fontSize = 8, nodeWidth = 30, colourScale=my_color, NodeGroup="group",LinkGroup="group")

還有一個(gè)問(wèn)題,真?zhèn)€生成的是html,如果我們想轉(zhuǎn)化成我們常規(guī)的圖片格式,需要安裝這個(gè)包:
install.packages("webshot")
?if(!is_phantomjs_installed()){
? install_phantomjs()
}
library(webshot)
sn<-sankeyNetwork(Links = links, Nodes = nodes, Source = "source",
? ? ? ? ? ? ? Target = "target", Value = "value", NodeID = "name",
? ? ? ? ? ? ? units = "TWh", fontSize = 8, nodeWidth = 30, colourScale=my_color, NodeGroup="group",LinkGroup="group")
saveNetwork(sn, "sn.html")
webshot("sn.html" , "sn.pdf")
就可以存成pdf格式了。