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…

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

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 设置跳转快捷键

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

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

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…

Python版《消消乐》,附源码

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

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;这篇文…

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…

tensorrt-llm与vllm的量化性能比较

准备部署lora微调好的语言大模型&#xff0c;有tensorrt-llm和vllm两种加速策略可选&#xff0c;而量化策略也有llm.int8&#xff0c;gptq&#xff0c;awq可用&#xff0c; 怎样的组合才能获得最佳精度与速度呢&#xff0c;这是个值得探讨的问题&#xff0c;本文以llama-factor…

代理记账公司的五大问题及其解决方案

代理记账公司是现代企业管理中不可或缺的一部分&#xff0c;它为企业的日常运营提供了专业、高效的服务&#xff0c;随着行业的发展和竞争的加剧&#xff0c;代理记账公司的面临的问题也日益突出&#xff0c;这些问题主要表现在以下几个方面&#xff1a; 业务流程不规范 许多代…

【前端】display:none和visibility:hidden两者的区别

&#x1f60e; 作者介绍&#xff1a;我是程序员洲洲&#xff0c;一个热爱写作的非著名程序员。CSDN全栈优质领域创作者、华为云博客社区云享专家、阿里云博客社区专家博主。公粽号&#xff1a;洲与AI。 &#x1f913; 欢迎大家关注我的专栏&#xff0c;我将分享Web前后端开发、…

C语言 | Leetcode C语言题解之第132题分割回文串II

题目&#xff1a; 题解&#xff1a; int minCut(char* s) {int n strlen(s);bool g[n][n];memset(g, 1, sizeof(g));for (int i n - 1; i > 0; --i) {for (int j i 1; j < n; j) {g[i][j] (s[i] s[j]) && g[i 1][j - 1];}}int f[n];for (int i 0; i <…

YOLOv8改进 | Conv篇 | 利用YOLOv10提出的C2fUIB魔改YOLOv8(附代码 + 完整修改教程)

一、本文介绍 本文给大家带来的改进机制是利用YOLOv10提出的C2fUIB模块助力YOLOv8进行有效涨点&#xff0c;其中C2fUIB模块所用到的CIB模块是一种紧凑的倒置块结构&#xff0c;它采用廉价的深度卷积进行空间混合&#xff0c;并采用成本效益高的点卷积进行通道混合。本文针对该…

AI大数据统计《庆余年2》中的小人物有哪些?

《庆余年2》除了主角表演经常&#xff0c;每个配角小人物也很出彩。那到底有哪些小人物呢&#xff1f; 在deepseek中输入提示词&#xff1a; 你是一个Python编程专家&#xff0c;要写一个Python脚本&#xff0c;具体步骤如下&#xff1a; 读取文档&#xff1a;"D:\qyn\…

数据结构与算法之Floyd弗洛伊德算法求最短路径

目录 前言 Floyd弗洛伊德算法 定义 步骤 一、初始化 二、添加中间点 三、迭代 四、得出结果 时间复杂度 代码实现 结束语 前言 今天是坚持写博客的第18天&#xff0c;希望可以继续坚持在写博客的路上走下去。我们今天来看看数据结构与算法当中的弗洛伊德算法。 Flo…

Leetcode3164. 优质数对的总数 II

Every day a Leetcode 题目来源&#xff1a;3164. 优质数对的总数 II 解法1&#xff1a;统计因子 遍历 nums1&#xff0c;统计所有元素的因子个数&#xff0c;记录到哈希表 cnt 中。 遍历 nums2&#xff0c;那么有 cnt[nums2[i]*k] 个数可以被 nums2[i]*k 整除&#xff0c;…

利用conda进行R的安装

1.miniconda3的安装 官网&#xff1a;Miniconda — Conda documentation 找到对应系统、Python版本下载 wget https://mirrors.ustc.edu.cn/anaconda/miniconda/Miniconda3-latest-Linux-x86_64.sh #wget -c https://repo.continuum.io/miniconda/Miniconda3-latest-Linux-x…