You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为Sankey图设置独立的节点与连接线颜色

问题描述

我正在制作Sankey图,希望为节点和连接线设置独立颜色(理想状态下连接线与源节点同色)。查阅各类论坛并编写相关颜色设置代码后,生成的Sankey图仅显示部分内容且全为黑色。以下是我的代码:

数据准备代码

library(networkD3)

## create a dataframe with 10 nodes
nodes = data.frame("name" = c("0", "1", "2", "3", "4", "5", "6", "7",
                              "8", "9", "10", "11", "12"))

#Create column column to nodes dataframe for colours
nodeColor <- c("#50A14D", "#52CC4E", "#9D73E6", "#F54F4F", "#F7A85E", "#9D73E6", "#F54F4F", "#F7A85E",
               "#ADFBFF", "#ADDAFF", "#ADC3FF", "#BBADFF", "#E9ADFF")

#Add colour column to nodes dataframe
nodes["nodesColor"] <-nodeColor

#Set Colours for each group
mycolor <- 'd3.scaleOrdinal() .domain(["0", "1", "2", "3", "4", "5", "6", "7"]).range
                                      (["#50A14D", "#52CC4E" ,"#9D73E6", "#F54F4F", "#F7A85E", "#9D73E6",
                                        "#F54F4F", "#F7A85E"])'

## create links with values (1st number = Source, 2nd number = Target, 3rd number = Value)
links = as.data.frame(matrix(c(0, 2, 10, 
                               0, 3, 212,
                               0, 4, 84,
                               1, 2, 7,
                               1, 3, 13,
                               1, 4, 70,
                               2, 5, 102,
                               2, 6, 8,
                               2, 7, 36,
                               3, 5, 11,
                               3, 6, 102,
                               3, 7, 29,
                               4, 5, 8,
                               4, 6, 8,
                               4, 7, 176,
                               5, 8, 51,
                               5, 9, 32,
                               5, 10, 24,
                               5, 11, 8,
                               5, 12, 12,
                               6, 8, 82,
                               6, 9, 42,
                               6, 10, 41,
                               6, 11, 11,
                               6, 12, 23,
                               7, 8, 25,
                               7, 9, 27,
                               7, 10, 22,
                               7, 11, 3,
                               7, 12, 8
                                
), byrow = TRUE, ncol = 3))

#Create Grouping Column for Colours
group <- c(0,0,0,1,1,1,2,2,2,3,3,3,4,4,4,5,5,5,5,5,6,6,6,6,6,7,7,7,7,7)

#Add Group Column to Links dataframe
links["group"] <- group

## set column names for links
names(links) = c("source", "target", "value", "group")

绘图代码

sankeyNetwork(
  Links = links,
  Nodes = nodes,
  Source = "source",
  Target = "target",
  Value  = "value",
  NodeID = "name",
  LinkGroup = "group",
  colourScale = mycolor,
  fontFamily = "Arial",
  nodeWidth = 15,
  fontSize = 12,
  width  = 400,
  height = 300)

问题分析与解决办法

你的代码存在两个核心问题导致显示异常:

  1. 颜色映射不匹配:colourScale中定义的domain是字符串类型的节点名称,但links$group是数值类型,两者无法匹配,导致颜色失效。
  2. 节点颜色未生效:没有指定NodeColour参数调用节点的颜色列。
  3. 尺寸不足:设置的宽高过小,导致部分内容被截断。

针对"连接线与源节点同色"的需求,修改后的完整代码如下:

library(networkD3)

# 节点数据:直接整合颜色列
nodes = data.frame(
  name = c("0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12"),
  nodesColor = c("#50A14D", "#52CC4E", "#9D73E6", "#F54F4F", "#F7A85E", "#9D73E6", "#F54F4F", "#F7A85E",
                 "#ADFBFF", "#ADDAFF", "#ADC3FF", "#BBADFF", "#E9ADFF")
)

# 链接数据
links = as.data.frame(matrix(c(0, 2, 10, 
                               0, 3, 212,
                               0, 4, 84,
                               1, 2, 7,
                               1, 3, 13,
                               1, 4, 70,
                               2, 5, 102,
                               2, 6, 8,
                               2, 7, 36,
                               3, 5, 11,
                               3, 6, 102,
                               3, 7, 29,
                               4, 5, 8,
                               4, 6, 8,
                               4, 7, 176,
                               5, 8, 51,
                               5, 9, 32,
                               5, 10, 24,
                               5, 11, 8,
                               5, 12, 12,
                               6, 8, 82,
                               6, 9, 42,
                               6, 10, 41,
                               6, 11, 11,
                               6, 12, 23,
                               7, 8, 25,
                               7, 9, 27,
                               7, 10, 22,
                               7, 11, 3,
                               7, 12, 8
), byrow = TRUE, ncol = 3))

names(links) = c("source", "target", "value")

# 让链接group等于源节点名称,确保连接线与源节点颜色匹配
# 注意:networkD3节点索引从0开始,R数据框索引从1开始,所以要+1
links$group = nodes$name[links$source + 1]

# 完整颜色映射:覆盖所有节点,确保链接和节点颜色一一对应
mycolor <- 'd3.scaleOrdinal()
  .domain(["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12"])
  .range(["#50A14D", "#52CC4E", "#9D73E6", "#F54F4F", "#F7A85E", "#9D73E6", "#F54F4F", "#F7A85E",
          "#ADFBFF", "#ADDAFF", "#ADC3FF", "#BBADFF", "#E9ADFF"])'

# 绘制Sankey图
sankeyNetwork(
  Links = links,
  Nodes = nodes,
  Source = "source",
  Target = "target",
  Value  = "value",
  NodeID = "name",
  LinkGroup = "group",
  NodeColour = "nodesColor",  # 指定节点颜色列
  colourScale = mycolor,
  fontFamily = "Arial",
  nodeWidth = 15,
  fontSize = 12,
  width  = 800,  # 增大宽度以显示完整内容
  height = 600
)

关键修改说明

  • 链接颜色匹配:将links$group设置为对应源节点的名称,确保与colourScale的domain完全匹配,实现连接线与源节点同色。
  • 节点颜色生效:添加NodeColour = "nodesColor"参数,启用节点数据中的自定义颜色列。
  • 完整颜色映射:更新colourScale的domain,包含所有节点名称,避免颜色遗漏。
  • 尺寸调整:增大宽高参数,确保所有节点和连线完整显示。

内容的提问来源于stack exchange,提问作者Paul

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 22:35:18