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 多平台发布

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/22596.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

VUE3 学习笔记(14):VUE3 组合式API与传统选项式API用法

VUE3相较VUE2的亮点很多&#xff0c;作为后端开发置于前端最大的感受就是组合式API&#xff08;之前采用的是选项式API&#xff09;&#xff1b;它使得整体更简洁易用,但值得提醒的是官方并未强制要求二选一&#xff0c;尽管如此在同一个项目中还是不要出现两种写法。 选项式AP…

详解大模型微调数据集构建方法(持续更新)

大家好,我是herosunly。985院校硕士毕业,现担任算法t研究员一职,热衷于机器学习算法研究与应用。曾获得阿里云天池比赛第一名,CCF比赛第二名,科大讯飞比赛第三名。拥有多项发明专利。对机器学习和深度学习拥有自己独到的见解。曾经辅导过若干个非计算机专业的学生进入到算…

【通知】上市公司嵌入式工程师带队授课,成品展示~~

1&#xff0c;成品展示&#xff1a; 2&#xff0c;产品需求&#xff1a; 设计一款无线CAN转发器&#xff0c;由若干个终端组成&#xff0c;若干个终端之间可以将接收到的CAN数据通过无线的方式转发出去&#xff0c;在复杂的条件下&#xff0c;传输距离不低于200m。 该CAN转发器…

vscode+latex设置跳转快捷键

安装参考 https://blog.csdn.net/Hacker_MAI/article/details/130334821 设置默认recipe ctrl P 打开设置&#xff0c;搜索recipe 也可以点这里看看有哪些配置 2 设置跳转快捷键

leetcode7 整数翻转

给你一个 32 位的有符号整数 x &#xff0c;返回将 x 中的数字部分反转后的结果。 如果反转后整数超过 32 位的有符号整数的范围 [−231, 231 − 1] &#xff0c;就返回 0。 假设环境不允许存储 64 位整数&#xff08;有符号或无符号&#xff09;。 示例 1&#xff1a; 输入…

[AIGC] @Component与@Bean的区别详解

在Spring框架中&#xff0c;Component和Bean常常被用来进行依赖注入&#xff0c;让Spring自身管理对象的生命周期。然而&#xff0c;尽管它们将目标类标记为Spring容器中的构件&#xff0c;但是二者的应用场景和工作方式存在重要的区别。 文章目录 ComponentBean主要区别 Compo…

IIC信号质量测试、时序测试详解

IIC 时序图 信号质量测试 1、vIL: 低输入电平。 2、vIH: 高输入电平。 3、vhys: 施密特触发器输入的滞后。 4、vOL1: VDD>2V时&#xff0c;低电平输出电压&#xff08;漏极开路或集电极开路&#xff09;。 5、vOL3: VDD<2V时&#xff0c;低电平输出电压&#xff08;漏极开…

【Vue】水果购物车-基本渲染

在Vue中&#xff0c;如果想要实现全选反选功能&#xff0c;通常使用计算属性 完整代码 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><meta http-equiv"X-UA-Compatible" content"IEedge&qu…

Spring中的事务是如何实现的

Spring里的事务管理&#xff0c;你可以想象成是银行里的一个业务办理过程。就像你在银行办转账时&#xff0c;要么全部完成&#xff08;钱从一个账户转到另一个账户&#xff09;&#xff0c;要么什么都不变&#xff08;如果中间出问题了&#xff0c;钱不会丢失&#xff09;。Sp…

JMeter Plugins Manager---插件安装

参考文章&#xff1a;https://blog.51cto.com/u_14126/6291032 需求&#xff1a; 安装【jpgc - Standard Set】插件 常用插件&#xff1a; 点击下载–报错如下&#xff1a; Failed to apply changes:Cannotapplychanges:Haveno write accessforJMeterdirectories,notpossib…

Element Plus使用总结

一、引言 Element Plus是一套为开发者、设计师和产品经理准备的基于Vue 3的组件库&#xff0c;它继承了Element UI的优点&#xff0c;同时进行了诸多改进和优化&#xff0c;使其更加适用于现代Web应用的开发。以下是对Element Plus使用的总结。 二、安装与引入 安装&#xf…

JavaScript 中创建函数的多种方式

在 JavaScript 中&#xff0c;可以通过多种方式创建函数。每种方式都有其特定的用途、优点和缺点&#xff0c;以及适用的使用场景。以下是几种常见的创建函数的方式及其详细说明。 1. 函数声明&#xff08;Function Declaration&#xff09; 示例 function add(a, b) {retur…

Python版《消消乐》,附源码

曾经风靡一时的消消乐&#xff0c;至今坐在地铁上都可以看到很多人依然在玩&#xff0c;想当年我也是大军中的一员&#xff0c;那家伙&#xff0c;吃饭都在玩&#xff0c;进入到高级的那种胜利感还是很爽的&#xff0c;连续消&#xff0c;无限消&#xff0c;哈哈&#xff0c;现…

60、最大公约数

最大公约数 题目描述 给定n对正整数ai,bi&#xff0c;请你求出每对数的最大公约数。 输入格式 第一行包含整数n。 接下来n行&#xff0c;每行包含一个整数对ai,bi。 输出格式 输出共n行&#xff0c;每行输出一个整数对的最大公约数。 数据范围 1 ≤ n ≤ 1 0 5 , 1≤n≤…

0基础学习区块链技术——去中心化

“去中心化”是区块链技术的核心。那么我们该如何理解这个概念呢&#xff1f; 我们可以假想在一次现实转账中&#xff0c;有哪些“中心化”的行为&#xff1a; 判断余额是否足够。即判断转出的钱是否少于账户里剩余的钱&#xff0c;能够判断的是账户所在的银行。 如果余额足够…

读AI未来进行式笔记03自然语言处理技术

1. AI伙伴 1.1. 作为AI能力的集大成者&#xff0c;AI伙伴融合了各种复杂的AI技术 1.2. 人类唯一可能超越AI的领域&#xff0c;只可能在机器无法触及之处&#xff0c;那是属于人类感性与直觉的领域 1.3. 要读懂人类&#xff0c;需要漫长而平缓的学习过程 1.4. AI塑造了我们&…

I.MX RT1170之MIPI CSI摄像头初始化和显示流程详解

在上一篇文章I.MX RT1170之MIPI DSI初始化和显示流程详解中&#xff0c;我们介绍了RT1170单片机中MIPI DSI显示屏初始化和显示的详细步骤&#xff0c;那这一节就来介绍MIPI的另一个接口应用&#xff1a;摄像头CSI的初始化和配置流程。 对于摄像头来说&#xff0c;一般我们还要…

Adobe XD最新版号查询,如何使用?

Adobe XD是Adobe家推出的基于矢量的原型设计合作工具&#xff0c;被业界视为应对Sketch的“对抗”产品。Adobe XD不同于Sketch的系统限制&#xff0c;灵活性比较高&#xff0c;Windows和Mac都可以使用。自2017年推出以来&#xff0c;Adobe XD版经历了多次更新&#xff0c;这篇文…

Ratchet websocket token 验证

Ratchet websocket token 验证 in javascript: new WebSocket(ws://server.com:8080?tokensecret) in php: public function onOpen(ConnectionInterface $conn) {$querystring $conn->httpRequest->getUri()->getQuery();parse_str($querystring,$queryarray);if…

Android RelativeLayout Rtl布局下的bug:paddingStart会同时作用于左右内边距

问题现象 如上图&#xff0c;只是设置了paddingStart&#xff0c;在RTL布局下&#xff0c;左右都产生了10dp的间距。其他布局如LinearLayout&#xff0c;FrameLayout则没有这个问题。 private void positionAtEdge(View child, LayoutParams params, int myWidth) {if (isLayou…