桑基圖(Sankey diagram),即桑基能量分流圖,也叫桑基能量平衡圖。它是一種特定類型的流程圖,圖中延伸的分支的寬度對應數據流量的大小,通常應用於能源、材料成分、金融、生物信息等數據的可視化分析。因1898年Matthew Henry Phineas Riall Sankey繪制的“蒸汽機的能源效率圖”而聞名,此后便以其名字命名為“桑基圖”。
前兩天正好碰到了這類“數據流量”的可視化問題,因此花了點時間學習了一下桑基圖的畫法,比較簡單,在這里給大家演示一下:
我自己編了一個數據,如下圖所示
左邊是數據的流向,右邊是用表格的形式重寫,左圖的每一個箭頭對應右圖的每一行,畫桑基圖時用到的數據就是右邊格式的表格。
下面就是代碼
library(networkD3)
library(tidyverse)
library(RColorBrewer)
#讀取剛才的數據框,給列命名
df=read.table("test.txt",header = F,sep = "\t",stringsAsFactors = F)
colnames(df)=c("source","target","value")
#圖形中的所有節點
df.nodes <- data.frame(
name=c(as.character(df$source),
as.character(df$target)) %>% unique()
)
#將source和target重新編號
df$IDsource <- match(df$source, df.nodes$name)-1
df$IDtarget <- match(df$target, df.nodes$name)-1
#這一步是為了給flow自定義顏色,單獨定義了一列
df$group="flow"
#配置顏色部分,形式相對固定,不必糾結具體的語法規則
#編碼對應的顏色可以用RColorBrewer包結合scales包查看
my_color <- 'd3.scaleOrdinal()
.domain(["A", "B", "C", "D", "E", "F", "G", "H", "I", "J","flow"])
.range(["#8DD3C7", "#FFFFB3", "#BEBADA", "#FB8072", "#80B1D3", "#FDB462", "#B3DE69", "#FCCDE5", "#BC80BD", "#CCEBC5","#BDBDBD"])'
#畫圖
Sankey.p <- sankeyNetwork(Links = df, Nodes = df.nodes,
Source = "IDsource", Target = "IDtarget",
Value = "value", NodeID = "name", LinkGroup = "group",colourScale=my_color,
sinksRight=FALSE, nodeWidth=25, nodePadding=10, fontSize=13,width=900)
Sankey.p
#畫出來的圖形,還可以直接在R窗口中調整方塊上下位置,不過還是建議保存為pdf后用AI調整
#nodeWidth每個節點方塊的寬度
#nodePadding每一列節點方塊之間在縱向上的間隔
#width是圖形橫向的寬度
#保存為pdf
library(htmlwidgets)
saveWidget(Sankey.p, file="Sankey.html")
library(webshot)
webshot("Sankey.html", "Sankey.pdf")
最后的效果是這樣的,嗯...還需調整
公眾號后台回復20210325,獲取今天的代碼和測試數據
因水平有限,有錯誤的地方,歡迎批評指正!