当前位置: 首页 > news >正文

R语言绘图 --- 桑基图(Biorplot 开发日志 --- 5)

「写在前面」

在科研数据分析中我们会重复地绘制一些图形,如果代码管理不当经常就会忘记之前绘图的代码。于是我计划开发一个 R 包(Biorplot),用来管理自己 R 语言绘图的代码。本系列文章用于记录 Biorplot 包开发日志。


相关链接

相关代码和文档都存放在了 Biorplot GitHub 仓库:
https://github.com/zhenghu159/Biorplot

欢迎大家 Follow 我的 GitHub 账号:
https://github.com/zhenghu159

我会不定期更新生物信息学相关工具和学习资料。如果您有任何问题和建议,或者想贡献自己的代码,请在我的 GitHub 上留言。

介绍

桑基图,是一种特定类型的流程图,图中延伸的分支的宽度对应数据流量的大小,比较适用于用户流量等数据的可视化分析。

Biorplot 中,我封装了 Bior_SankeyPlot() 函数来实现桑基图的绘制。

基础桑基图

绘制一个基础的桑基图如下:

alt

绘图代码:

links <- data.frame(
Source=c("C","A", "B", "E", "D"),
Target=c("b","c", "a", "e", "d"),
Value=c(1, 2, 1, 4, 5)
)
nodes <- data.frame(
name = c("A", "B", "C", "D", "E", "a", "b", "c", "d", "e")
)
links$IDsource <- match(links$Source, nodes$name) -1
links$IDtarget <- match(links$Target, nodes$name) -1
Nodes.colour <- c("#1F77B4B2","#FF7F0EB2","#2CA02CB2","#D62728B2","#9467BDB2",
"#8C564BB2","#E377C2B2","#7F7F7FB2","#BCBD22B2","#17BECFB2")

p <- Bior_SankeyPlot(links, nodes, Nodes.colour=Nodes.colour, Nodes.order = nodes$name,
fontSize=20,iterations=0)
p
# save plot
# saveNetwork(p,"sankey.html")
# webshot("sankey.html", "sankey.pdf")

多层桑基图

绘制一个多层桑基图,并自定义颜色:

alt

绘图代码:

links <- data.frame(
Source = c(rep(c("A_1","B_1","C_1","D_1"),each=4), rep(c("A_2","B_2","C_2","D_2"),each=4)),
Target = c(rep(c("A_2","B_2","C_2","D_2"),4), rep(c("A_3","B_3","C_3","D_3"),4)),
Value = c(0.4,0.4,0.1,0.1, 0.1,0.8,0.05,0.05, 0.05,0.05,0.8,0.1, 0.05,0.1,0.05,0.8,
0.4,0.4,0.1,0.1, 0.1,0.8,0.05,0.05, 0.05,0.05,0.8,0.1, 0.05,0.1,0.05,0.8)
)
links$Group <- ""
links$Group[which(links$Value > 0.5)] <- "Type1"
links$Group[which(links$Value > 0.1 & links$Value <= 0.5)] <- "Type2"
links$Group[which(links$Value <= 0.1)] <- "Type3"
nodes <- data.frame(
name = c("A_1","B_1","C_1","D_1","A_2","B_2","C_2","D_2","A_3","B_3","C_3","D_3")
)
links$IDsource <- match(links$Source, nodes$name) - 1
links$IDtarget <- match(links$Target, nodes$name) - 1
Group.order <- c("Type1", "Type2", "Type3")
Group.colour <- c("#6860ff","#e489dc","#d0d5da")
Nodes.order <- nodes$name
Nodes.colour <- rep(c('#ffda11', '#f68d45', '#26d5ff', '#f05a9e'),3)

Bior_SankeyPlot(
Links = links, Nodes = nodes, Source = "IDsource", Target = "IDtarget",
Value = "Value", NodeID = "name", colourScale = colourScale, LinkGroup="Group",
fontSize = 20, iterations=0,
Group.order = Group.order, Group.colour = Group.colour,
Nodes.order = Nodes.order, Nodes.colour = Nodes.colour)

源码解析

Biorplot::Bior_SankeyPlot() 函数主要继承了 networkD3::sankeyNetwork() 函数。并新增了节点和分组顺序、颜色设置参数:

  • Group.order (defaut: Group.order=NULL); text size Set Group order
  • Group.colour (defaut: Group.colour=NULL); Set Group colour
  • Nodes.order (defaut: Nodes.order=NULL); Set nodes order
  • Nodes.colour (defaut: Nodes.colour=NULL); Set Nodes colour

源码:

#%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

#' Sankey Plot
#' @description Create a sankey plot.
#'
#' @importFrom networkD3 sankeyNetwork
#'
#' @inheritParams networkD3::sankeyNetwork
#'
#' @param Group.order (defaut: Group.order=NULL); text size Set Group order
#' @param Group.colour (defaut: Group.colour=NULL); Set Group colour
#' @param Nodes.order (defaut: Nodes.order=NULL); Set nodes order
#' @param Nodes.colour (defaut: Nodes.colour=NULL); Set Nodes colour
#'
#' @export
#'
#' @examples
#' # Examples 1
#' links <- data.frame(
#' Source=c("C","A", "B", "E", "D"),
#' Target=c("b","c", "a", "e", "d"),
#' Value=c(1, 2, 1, 4, 5)
#' )
#' nodes <- data.frame(
#' name = c("A", "B", "C", "D", "E", "a", "b", "c", "d", "e")
#' )
#' links$IDsource <- match(links$Source, nodes$name) -1
#' links$IDtarget <- match(links$Target, nodes$name) -1
#' Nodes.colour <- c("#1F77B4B2","#FF7F0EB2","#2CA02CB2","#D62728B2","#9467BDB2",
#' "#8C564BB2","#E377C2B2","#7F7F7FB2","#BCBD22B2","#17BECFB2")
#'
#' p <- Bior_SankeyPlot(links, nodes, Nodes.colour=Nodes.colour, Nodes.order = nodes$name,
#' fontSize=20,iterations=0)
#' p
#' # save plot
#' # saveNetwork(p,"sankey.html")
#' # webshot("sankey.html" , "sankey.pdf")
#'
#'
#' # Examples 2
#' links <- data.frame(
#' Source = c(rep(c("A_1","B_1","C_1","D_1"),each=4), rep(c("A_2","B_2","C_2","D_2"),each=4)),
#' Target = c(rep(c("A_2","B_2","C_2","D_2"),4), rep(c("A_3","B_3","C_3","D_3"),4)),
#' Value = c(0.4,0.4,0.1,0.1, 0.1,0.8,0.05,0.05, 0.05,0.05,0.8,0.1, 0.05,0.1,0.05,0.8,
#' 0.4,0.4,0.1,0.1, 0.1,0.8,0.05,0.05, 0.05,0.05,0.8,0.1, 0.05,0.1,0.05,0.8)
#' )
#' links$Group <- ""
#' links$Group[which(links$Value > 0.5)] <- "Type1"
#' links$Group[which(links$Value > 0.1 & links$Value <= 0.5)] <- "Type2"
#' links$Group[which(links$Value <= 0.1)] <- "Type3"
#' nodes <- data.frame(
#' name = c("A_1","B_1","C_1","D_1","A_2","B_2","C_2","D_2","A_3","B_3","C_3","D_3")
#' )
#' links$IDsource <- match(links$Source, nodes$name) - 1
#' links$IDtarget <- match(links$Target, nodes$name) - 1
#' Group.order <- c("Type1", "Type2", "Type3")
#' Group.colour <- c("#6860ff","#e489dc","#d0d5da")
#' Nodes.order <- nodes$name
#' Nodes.colour <- rep(c('#ffda11', '#f68d45', '#26d5ff', '#f05a9e'),3)
#'
#' Bior_SankeyPlot(
#' Links = links, Nodes = nodes, Source = "IDsource", Target = "IDtarget",
#' Value = "Value", NodeID = "name", colourScale = colourScale, LinkGroup="Group",
#' fontSize = 20, iterations=0,
#' Group.order = Group.order, Group.colour = Group.colour,
#' Nodes.order = Nodes.order, Nodes.colour = Nodes.colour)
#'
Bior_SankeyPlot <- function(Links, Nodes, Source = "IDsource", Target = "IDtarget",
Value = "Value", NodeID = "name", NodeGroup = NodeID,
LinkGroup = NULL, units = "",
colourScale = JS("d3.scaleOrdinal(d3.schemeCategory20);"), fontSize = 7,
fontFamily = NULL, nodeWidth = 15, nodePadding = 10, margin = NULL,
height = NULL, width = NULL, iterations = 32, sinksRight = TRUE,
Group.order=NULL, Group.colour=NULL,
Nodes.order=NULL, Nodes.colour=NULL)
{

if (is.null(Group.order)){
Group.order <- sort(unique(Links$Group))
}
if (is.null(Nodes.order)){
Nodes.order <- Nodes$name
}

if ((!is.null(Group.order)) & (is.null(Nodes.order))){
domain <- c(Group.order)
range <- c(Group.colour)
}else if ((is.null(Group.order)) & (!is.null(Nodes.order))){
domain <- c(Nodes.order)
range <- c(Nodes.colour)
}else if ((!is.null(Group.order)) & (!is.null(Nodes.order))){
domain <- c(Group.order, Nodes.order)
range <- c(Group.colour, Nodes.colour)
}else{
domain <- NULL
range <- NULL
}

colourScale <- paste('d3.scaleOrdinal() .domain(["', domain[1], sep = '')
for (i in 2:length(domain)){
colourScale <- paste(colourScale, '", "', domain[i], sep = '')
}
colourScale <- paste(colourScale, '"]) .range(["', sep = '')
colourScale <- paste(colourScale, range[1], sep = '')
for (i in 2:length(range)){
colourScale <- paste(colourScale,'", "', range[i], sep = '')
}
colourScale <- paste(colourScale,'"])', sep = '')

if (is.null(domain) & is.null(range)){
colourScale <- "d3.scaleOrdinal(d3.schemeCategory20);"
}

p <-
sankeyNetwork(
Links = Links, Nodes = Nodes, Source = Source, Target = Target,
Value = Value, NodeID = NodeID, NodeGroup = NodeID,
LinkGroup = LinkGroup, units = units,
colourScale = colourScale, fontSize = fontSize,
fontFamily = fontFamily, nodeWidth = nodeWidth, nodePadding = nodePadding,
margin = margin,
height = height, width = width, iterations = iterations, sinksRight = sinksRight)

return(p)
}

#%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

「结束」

注:本文为个人学习笔记,仅供大家参考学习,不得用于任何商业目的。如有侵权,请联系作者删除。

alt

本文由 mdnice 多平台发布

相关文章:

  • Win10下CodeBlock实现socket TCP server/client
  • CSS--超出就显示滚动条并设置滚动条的样式
  • LeetCode 每日一题 2024/6/3-2024/6/9
  • Qt——窗口
  • RabbitMQ从入门到入土
  • 什么是校园抄表系统?
  • 基于SOA海鸥优化算法的三维曲面最高点搜索matlab仿真
  • ABSD方法论:一种有效的软件开发方法
  • 网络故障排除:保持网络稳定与业务连续
  • esp32s3-gc9a01-lvgl
  • 爬取京东商品图片的Python实现方法
  • 跨国大文件传输需要哪些方面?怎么实现数据快速传输?
  • 堡垒机的自动化运维,快速安全提升运维效率
  • 基于电压矢量变换的锁相环simulink建模与仿真
  • 【大数据-算法】资源调度算法:动态资源分配策略的深入探讨
  • 【162天】黑马程序员27天视频学习笔记【Day02-上】
  • Laravel 中的一个后期静态绑定
  • leetcode386. Lexicographical Numbers
  • mysql外键的使用
  • Puppeteer:浏览器控制器
  • Python 使用 Tornado 框架实现 WebHook 自动部署 Git 项目
  • Solarized Scheme
  • WebSocket使用
  • 从伪并行的 Python 多线程说起
  • 设计模式(12)迭代器模式(讲解+应用)
  • 自动记录MySQL慢查询快照脚本
  • mysql面试题分组并合并列
  • ​configparser --- 配置文件解析器​
  • #{}和${}的区别是什么 -- java面试
  • #define MODIFY_REG(REG, CLEARMASK, SETMASK)
  • #define、const、typedef的差别
  • #Z2294. 打印树的直径
  • (Java入门)学生管理系统
  • (vue)el-checkbox 实现展示区分 label 和 value(展示值与选中获取值需不同)
  • (不用互三)AI绘画:科技赋能艺术的崭新时代
  • (附源码)springboot高校宿舍交电费系统 毕业设计031552
  • (附源码)计算机毕业设计SSM基于java的云顶博客系统
  • (离散数学)逻辑连接词
  • (四)activit5.23.0修复跟踪高亮显示BUG
  • (四)搭建容器云管理平台笔记—安装ETCD(不使用证书)
  • (贪心 + 双指针) LeetCode 455. 分发饼干
  • (一)utf8mb4_general_ci 和 utf8mb4_unicode_ci 适用排序和比较规则场景
  • (译)2019年前端性能优化清单 — 下篇
  • (转)3D模板阴影原理
  • .chm格式文件如何阅读
  • .Net 6.0 监听Windows网络状态切换
  • .net core + vue 搭建前后端分离的框架
  • .NET LINQ 通常分 Syntax Query 和Syntax Method
  • .NET/C# 编译期间能确定的相同字符串,在运行期间是相同的实例
  • .NET和.COM和.CN域名区别
  • .net中应用SQL缓存(实例使用)
  • :如何用SQL脚本保存存储过程返回的结果集
  • ?php echo $logosrc[0];?,如何在一行中显示logo和标题?
  • @Autowired和@Resource装配
  • @Autowired注解的实现原理