R实用绘图--桑基图 / 冲击图 / networkD3

今天带领大家绘制的是桑基图(Sankey diagram),用于可视化流动、转移或转换过程中的能量、资源或数量。

桑基图主要由两个元素组成:节点和流线。节点代表不同的实体,而流线则表示这些实体之间的流动。

桑基图的特点是它能够清晰地展示复杂的流动关系,使观察者能够迅速理解系统中各个部分之间的相互作用和能量或资源的流动路径。这种图表常常用于能源管理、物流优化、资源分配等领域。

桑基图的名称来源于一名爱尔兰船长,最初他采用这种图展示了蒸汽的能源效率,所以该图以他的名字命名为桑基图。桑基图有时也会被称为流程图(flow diagram)或者冲击图(alluvial diagram)。

networkD3包主要用于绘制交互网络图,优点是语法简单、出图美观、可交互,缺点是功能较少,版本更新慢。

加载包

# 加载包
library(readxl)
library(tidyverse)
library(networkD3) #用于绘图
library(webshot) #用于图片格式转换

数据准备

示例数据已经保存为csv文件了,可以选择通过公众号后台获取示例数据或者自行运行该部分代码。

# 创造示例数据-----------------
## 第一层数据
data12 <- data.frame(source=sample(paste0('layer1_',1:4),100,
                                   prob = c(0.35,0.25,0.2,0.2),replace = T),
                    target=sample(paste0('layer2_',1:4),100,
                                  prob = c(0.3,0.3,0.2,0.2),replace = T))
layer12<- data12 %>%
  group_by(source, target) %>%
  summarise(weight = n())

## 第二层数据
data23 <- data.frame(source=data12$target,
                      target=sample(paste0('layer3_',1:8),100,
                                    prob = c(0.3,0.1,0.1,0.1,0.1,0.1,0.1,0.1),replace = T))
layer23<- data23 %>%
  group_by(source, target) %>%
  summarise(weight = n())

## 第三层数据
data34 <- data.frame(source=data23$target,
                     target=sample(paste0('layer4_',1:4),100,prob = c(0.4,0.2,0.2,0.2),replace = T))
layer34<- data34 %>%
  group_by(source, target) %>%
  summarise(weight = n())

## 合并三层数据
pdata <- rbind(layer12,layer23)
pdata <- rbind(pdata,layer34)

# 保存示例数据
write.csv(pdata,file = 'pdata.csv')

每一层的示例数据格式如下:weight表示相应source和target之间的关系权重。

示例数据

修改数据格式

# 创造示例数据-----------------
## 第一层数据
data12 <- data.frame(source=sample(paste0('layer1_',1:4),100,
                                   prob = c(0.35,0.25,0.2,0.2),replace = T),
                    target=sample(paste0('layer2_',1:4),100,
                                  prob = c(0.3,0.3,0.2,0.2),replace = T))
layer12<- data12 %>%
  group_by(source, target) %>%
  summarise(weight = n())

## 第二层数据
data23 <- data.frame(source=data12$target,
                      target=sample(paste0('layer3_',1:8),100,
                                    prob = c(0.3,0.1,0.1,0.1,0.1,0.1,0.1,0.1),replace = T))
layer23<- data23 %>%
  group_by(source, target) %>%
  summarise(weight = n())

## 第三层数据
data34 <- data.frame(source=data23$target,
                     target=sample(paste0('layer4_',1:4),100,prob = c(0.4,0.2,0.2,0.2),replace = T))
layer34<- data34 %>%
  group_by(source, target) %>%
  summarise(weight = n())

## 合并三层数据
pdata <- rbind(layer12,layer23)
pdata <- rbind(pdata,layer34)

# 保存示例数据
write.csv(pdata,file = 'pdata.csv')

修改数据格式

由于networkD3包要求source和target都是数值型数据,同时需要另外提供一个包含节点名称的数据框作为输入,因此我们需要修改数据格式。

# 修改为符合networkD3包要求的数据格式-------------------
# 创建节点名称数据框
nodes <- data.frame(name = c(as.character(pdata$source), 
                             as.character(pdata$target)) %>% unique())
# 把source、target转换为数字
pdata$IDsource = match(pdata$source, nodes$name)-1
pdata$IDtarget = match(pdata$target, nodes$name)-1
head(pdata)

绘图并保存

# 正式绘图---------------------------------------
p1 <- sankeyNetwork(Links = pdata, # 输入数据1
                    Nodes = nodes, # 输入数据2
                    Source = "IDsource", # 来源变量
                    Target = "IDtarget", # 接受变量
                    Value = "weight", # 关系权重
                    NodeID = "name", #节点名称
                    LinkGroup = 'source', # 颜色分组
                    sinksRight = FALSE, # 设置最后一层标签位置在左/右
                    nodeWidth = 5, #节点格子宽度
                    fontSize = 15, #文本标签字体的大小
                    nodePadding = 4) #节点格子间空隙宽度
p1

# 保存   
saveNetwork(p1,"sankey.html")
webshot("sankey.html" , "sankey.png")
webshot("sankey.html" , "sankey.pdf")

绘图效果

绘图展示

由于我们的数据是随机生成的,图可能看上去没有什么规律,而真实情况下的数据不同层之间可能会存在相关关系,真实数据的桑基图效果应该会更好。

此外,保存的html文件打开后各个节点和线都是可以拖动的,可以手动调整到更合适的位置。

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
桑基图(Sankey diagram)是一种流程,用于表示流量、能量、材料等资源在系统内部的转移。在R语言中,可以使用包ggplot2和ggalluvial来创建桑基图。 首先,我们需要安装并加载这两个包: ```r install.packages("ggplot2") install.packages("ggalluvial") library(ggplot2) library(ggalluvial) ``` 然后,我们可以使用以下代码创建一个简单的桑基图: ```r data <- data.frame(from = c("A", "A", "B", "B", "C"), to = c("B", "C", "C", "D", "D"), value = c(10, 20, 30, 40, 50)) ggplot(data, aes(axis1 = from, axis2 = to, y = value)) + geom_alluvium(aes(fill = from), width = 0.1) + geom_stratum(width = 1/8, fill = "grey", color = "black") + theme_void() ``` 这将创建一个包含三个节点的桑基图,其中节点A、B和C之间的流量表示为从A到B、从A到C、从B到C、从B到D和从C到D的线。 我们还可以自定义桑基图的颜色、标签和样式。例如,以下代码创建一个包含四个节点的桑基图,其中节点A、B、C和D之间的流量表示为从A到B、从A到C、从B到C、从B到D、从C到D和从C到A的线: ```r data <- data.frame(from = c("A", "A", "B", "B", "C", "C"), to = c("B", "C", "C", "D", "D", "A"), value = c(10, 20, 30, 40, 50, 60)) ggplot(data, aes(axis1 = from, axis2 = to, y = value)) + geom_alluvium(aes(fill = from), width = 0.1) + geom_stratum(width = 1/8, fill = "grey", color = "black") + scale_fill_manual(values = c("#E69F00", "#56B4E9", "#009E73", "#F0E442")) + ggtitle("Customized Sankey Diagram") + theme_void() + theme(plot.title = element_text(hjust = 0.5, size = 20, face = "bold"), axis.text.y = element_text(size = 16), axis.text.x = element_text(size = 16), axis.title = element_blank()) ``` 此代码将节点A、B、C和D分别着色为橙色、蓝色、绿色和黄色,并添加了标题和自定义字体大小和样式。 总之,R语言中的ggplot2和ggalluvial包提供了创建自定义桑基图的灵活和简单的方法,可以用于可视化各种类型的数据流程。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

皮肤小白生

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值