如何手动修改networkD3 Sankey网络图的节点颜色?
解决networkD3桑基图手动修改节点颜色的问题
要手动指定每个节点的颜色,你可以利用networkD3包中sankeyNetwork()函数的colourScale参数,结合D3.js的颜色比例尺来实现。下面是具体的修改方案:
方法1:直接为每个节点指定颜色
根据你现有节点的顺序(从Node0到Node6),创建一个对应颜色的数组,然后通过D3的scaleOrdinal比例尺将节点索引映射到指定颜色。
修改后的完整代码如下:
library(networkD3) # 原节点和链接数据 nodes = data.frame("name" = c("Mamalian", # Node 0 "Avian", # Node 1 "Critical", # Node 2 "Critical-maintained", # Node 3 "Endangerd", #Node 4 "Endangered-maintained", #Node 5 "Not at risk")) # Node 6 links = as.data.frame(matrix(c( 0, 2, 16, 0, 3, 2.2, 0, 4, 17.6, 0, 5, 7.0, 0, 6, 57.2, 1, 2, 23.9, 1, 3, 1.3, 1, 4, 24.7, 1, 5, 13.1, 1, 6, 37.0), byrow = TRUE, ncol = 3)) names(links) = c("source", "target", "value") # 定义每个节点对应的颜色(顺序和nodes中的节点一一对应) node_colors <- c("#E63946", "#457B9D", "#1D3557", "#A8DADC", "#F1FAEE", "#FFB703", "#FB5607") # 绘制桑基图,添加colourScale参数自定义颜色 sankeyNetwork(Links = links, Nodes = nodes, Source = "source", Target = "target", Value = "value", NodeID = "name", fontSize= 12, nodeWidth = 30, iterations = 0, colourScale = JS(paste0('d3.scaleOrdinal().domain(d3.range(0, ', nrow(nodes), ')).range(["', paste(node_colors, collapse = '", "'), '"])')))
方法2:给节点数据添加颜色列(更灵活)
如果你想把颜色和节点数据绑定,可以在nodes数据框中新增一列存储颜色,然后通过JS函数读取该列的值:
# 给nodes添加颜色列 nodes$color <- c("#E63946", "#457B9D", "#1D3557", "#A8DADC", "#F1FAEE", "#FFB703", "#FB5607") # 绘制桑基图,使用节点的color列定义颜色 sankeyNetwork(Links = links, Nodes = nodes, Source = "source", Target = "target", Value = "value", NodeID = "name", fontSize= 12, nodeWidth = 30, iterations = 0, colourScale = JS('d3.scaleOrdinal().domain(nodes.map(d => d.name)).range(nodes.map(d => d.color))'))
关键说明
- 颜色的顺序必须和
nodes数据框中节点的顺序完全对应,这样每个节点才能匹配到你想要的颜色。 - 你可以使用任意CSS颜色格式:十六进制(如
#FF0000)、RGB(如rgb(255,0,0))或颜色名称(如red)。 colourScale参数接受JavaScript代码字符串,所以我们用JS()函数把D3的颜色逻辑传入。
内容的提问来源于stack exchange,提问作者Warwick Wainwright




