如何为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)
问题分析与解决办法
你的代码存在两个核心问题导致显示异常:
- 颜色映射不匹配:
colourScale中定义的domain是字符串类型的节点名称,但links$group是数值类型,两者无法匹配,导致颜色失效。 - 节点颜色未生效:没有指定
NodeColour参数调用节点的颜色列。 - 尺寸不足:设置的宽高过小,导致部分内容被截断。
针对"连接线与源节点同色"的需求,修改后的完整代码如下:
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
相关产品推荐
相关产品推荐

