微生物16S/宏基因组/代谢组R 语言

【R画图学习4】桑基图

2022-10-16  本文已影响0人  jjjscuedu

桑基图,其实我用的不太多。最近常见还是在分析单细胞数据的时候,展示细胞通讯用的比较多的一种类型的图。例如下面一张就是cellchat画的一张桑基图。

x先看一下,百度对于桑基图的定义。桑基图(Sankey diagram),即桑基能量分流图,也叫桑基能量平衡图。它是一种特定类型的流程图,右图中延伸的分支的宽度对应数据流量的大小,通常应用于能源、材料成分、金融等数据的可视化分析。因1898年Matthew Henry Phineas Riall Sankey绘制的“蒸汽机的能源效率图”而闻名,此后便以其名字命名为“桑基图”。

所以从定义来看,一个简单的桑基图应该具备,node和link。node分为source node和target node。而link衡量source node和target node之间的数据流量的大小。

library(networkD3)

library(ggplot2)

我们先来设置一个简单的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")

从简单的测试数据来看,我们给定了4个node,并且设置了source node和target node之间的数据流动情况。需要注意的是node是从0开始计数的,这点和java一样。

sankeyNetwork(Links = links, Nodes = nodes,Source = "source", Target = "target",Value = "value", NodeID = "name",fontSize= 12, nodeWidth = 30)

出来就是一个简单的桑基图的样子。value表示这些链接与之关联的值,该值由链接的厚度表示。在示例中,连接节点A和节点B的第一条链接的宽度是连接A和C的第二条链接的宽度的一半。

这个函数的详细参数解释,大家也可以自己看下。Links指的就是我们输入的node之间的links文件,Nodes文件就是node的指定文件。Source,Target,Value和NodeID指定source、target、value和name。

下面测试一下我们自己的数据,先来一个简单点的。

这个是我们的第一个简单的测试数据:

links <- read.csv("links.csv",header = T, fileEncoding = "UTF-8-BOM")

nodes <- read.csv("nodes.csv", header = T, fileEncoding = "UTF-8-BOM")

我们从csv文件读入,后面fileEncoding主要是为了处理编码问题,有时候不知道为什么会出现乱码,主要是中文等格式的问题。

sankeyNetwork(Links = links, Nodes = nodes,

              Source = "source",

              Target = "target",

              Value = "value",

              NodeID = "name",

              fontSize = 12,

              nodeWidth = 30,

              nodePadding = 8

)

画图的函数和前面一样。而 fontSize = 12, 表示节点的字体大小;nodeWidth = 30, 表示节点的宽度;nodePadding = 8 表示节点之间的距离。

换个稍微复杂点的数据集试下:

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的颜色。

官网是这样说的:You can use this information to create a JavaScript color attribution object and call it using the Nodegroup argument.

就是我们可以自己创建一个javascript的颜色,好像java写的包,还真是麻烦。

my_color <- 'd3.scaleOrdinal() .domain(["c1", "c2","c3"]) .range(["red", "steelblue","green"])'   //我们根据每个node的group来指定颜色。

sankeyNetwork(Links = links, Nodes = nodes, Source = "source",

              Target = "target", Value = "value", NodeID = "name",

              units = "TWh", fontSize = 8, nodeWidth = 30, colourScale=my_color, NodeGroup="group")

感觉这个包颜色设置不太方面。

可以根据link的分类来分别设置颜色。

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")

还有一个问题,真个生成的是html,如果我们想转化成我们常规的图片格式,需要安装这个包:

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格式了。

上一篇 下一篇

猜你喜欢

热点阅读