使用用户定义的颜色修改networkD3 sankey图 [英] Modify networkD3 sankey plot with user-defined colors

查看:148
本文介绍了使用用户定义的颜色修改networkD3 sankey图的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在networkD3包中创建了一个sankey图.我想修改节点和链接的颜色和透明度.

I have a sankey plot created in networkD3 package. I would like to modify the colors and transparency of both nodes and links.

我的数据networkD3_data附加在末尾.

问题1:如何使用用户定义的调色板修改节点颜色?

我不确定如何使用用户定义的调色板修改颜色.对于我来说,必须使用特定于每个节点源的相同调色板,以与我拥有的其他图保持一致.

I am not sure how to modify the colors with user-defined palette. It is necessary for me to use the same color palette specific to each node source to keep consistent with other plots I have.

当前,通过定义NodeGroup,我能够使每个源节点具有不同的颜色,并使所有目标节点具有相同的颜色.下面的图很接近我想要的图,但是现在我要自己指定每个源节点的颜色.

Currently I am able to have each source node be a different color and all target nodes to be same color by defining the NodeGroup. The plot below is close to what I want, however now I want to specify the color of each source node myself.

library(networkD3)
sankeyNetwork(Links = networkD3_data$links, Nodes = networkD3_data$nodes, Source = "source", Target = "target", Value = "value", NodeID = "name", NodeGroup="group", fontSize=14)

?sankeyNetwork表示存在一个colourScale参数,该参数采用为节点指定分类颜色标度的字符串".我的意思是我可以在networkD3_data$nodes数据框中添加带有所需颜色的列,并这样调用colourScale:

?sankeyNetwork says there is a colourScale parameter which takes "character string specifying the categorical colour scale for the nodes". I took this to mean I can add a column with my desired colors to the networkD3_data$nodes data frame and call colourScale as such:

sankeyNetwork(Links = networkD3_data$links, Nodes = networkD3_data$nodes, Source = "source", Target = "target", Value = "value", NodeID = "name", NodeGroup="group", fontSize=14, colourScale="colors")

但是这不起作用,不会产生任何情节.我搜索了stackoverflow并找到了2014年的答案: ,但是我不认为这会行得通,因为当我出现错误Error: unexpected symbol调用这些建议的解决方案中的任何一个时(或者也许我只是不知道如何正确地实现此目的).

But this does not work, no plot is produced. I searched stackoverflow and found an answer from 2014: here, but I don't think this works anymore as I get an error Error: unexpected symbol calling either of these proposed solutions (or perhaps I just do not know how to implement this properly).

d3.scale.ordinal().range(["#7d3945","#e0677b", "#244457"])
d3.scaleOrdinal().range(["#7d3945","#e0677b", "#244457"])  

问题2:是否可以定义源和目标的显示顺序?

以便将源从Source0列出到Source10,将目标从Target11列出到Target47?这个在哪儿?我知道这与允许算法最佳地定位节点是违反直觉的.

So that sources are listed from Source0 to Source10 and targets from Target11 to Target47? Where is this set? I know this is counter-intuitive to allowing the algorithm to optimally position the nodes.

问题3:如何使用用户定义的调色板修改链接颜色并更改透明度/不透明度?

我还想使用与来源相同的配色方案对从来源发出的链接进行颜色编码.我可以通过定义LinkGroup来做到这一点,请参见下图.同样,我接近想要的颜色,但是我只需要指定自己使用的颜色即可,我不确定在哪里进行修改.我还想调整不透明度,以使源颜色比链接颜色更纯色.

I also want to color code the links emanating from the source using the same color scheme as the source. I am able to do this by defining LinkGroup, see plot below. Again I am close to what I want, but I just need to specify the colors used myself and I am not sure where to modify this. I also want to adjust the opacity so that the source color is more solid than the link colors.

sankeyNetwork(Links = networkD3_data$links, Nodes = networkD3_data$nodes, Source = "source", Target = "target", Value = "value", NodeID = "name", NodeGroup="group", LinkGroup="group", fontSize=14)

这是我的数据-dput(networkD3_data)

structure(list(nodes = structure(list(name = c("Source0", "Source1", 
"Source2", "Source3", "Source4", "Source5", "Source6", "Source7", 
"Source8", "Source9", "Source10", "Target11", "Target12", "Target13", 
"Target14", "Target15", "Target16", "Target17", "Target18", "Target19", 
"Target20", "Target21", "Target22", "Target23", "Target24", "Target25", 
"Target26", "Target27", "Target28", "Target29", "Target30", "Target31", 
"Target32", "Target33", "Target34", "Target35", "Target36", "Target37", 
"Target38", "Target39", "Target40", "Target41", "Target42", "Target43", 
"Target44", "Target45", "Target46", "Target47"), group = c("Source0", 
"Source1", "Source2", "Source3", "Source4", "Source5", "Source6", 
"Source7", "Source8", "Source9", "Source10", "Target", "Target", 
"Target", "Target", "Target", "Target", "Target", "Target", "Target", 
"Target", "Target", "Target", "Target", "Target", "Target", "Target", 
"Target", "Target", "Target", "Target", "Target", "Target", "Target", 
"Target", "Target", "Target", "Target", "Target", "Target", "Target", 
"Target", "Target", "Target", "Target", "Target", "Target", "Target"
), colors = c("#9E0142", "#D53E4F", "#F46D43", "#FDAE61", "#FEE08B", 
"#FFFFBF", "#E6F598", "#ABDDA4", "#66C2A5", "#3288BD", "#5E4FA2", 
"#969696", "#969696", "#969696", "#969696", "#969696", "#969696", 
"#969696", "#969696", "#969696", "#969696", "#969696", "#969696", 
"#969696", "#969696", "#969696", "#969696", "#969696", "#969696", 
"#969696", "#969696", "#969696", "#969696", "#969696", "#969696", 
"#969696", "#969696", "#969696", "#969696", "#969696", "#969696", 
"#969696", "#969696", "#969696", "#969696", "#969696", "#969696", 
"#969696")), .Names = c("name", "group", "colors"), row.names = c(NA, 
-48L), class = "data.frame"), links = structure(list(source = c(0, 
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 
3, 3, 3, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 
6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
8, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10
), target = c(11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 
23, 13, 18, 15, 11, 12, 24, 21, 25, 26, 27, 19, 28, 16, 22, 29, 
30, 31, 32, 18, 16, 15, 13, 27, 29, 19, 33, 34, 31, 35, 21, 24, 
11, 30, 36, 28, 37, 38, 39, 40, 26, 41, 11, 12, 15, 18, 19, 14, 
13, 16, 27, 34, 20, 22, 25, 12, 27, 16, 18, 13, 11, 12, 11, 14, 
27, 21, 16, 18, 22, 13, 15, 19, 16, 11, 12, 39, 12, 14, 18, 11, 
42, 43, 44, 13, 11, 18, 15, 12, 19, 45, 31, 16, 20, 46, 40, 47, 
11, 12, 18, 16, 14, 19, 15, 11, 12, 16, 13, 18, 14, 34, 31, 15
), value = c(5.8, 3.2, 5, 2.4, 2.5, 2.7, 3.5, 2.5, 3.5, 1.4, 
2.9, 2.4, 1.3, 12.1, 7.4, 5, 11.2, 5.6, 6.4, 8.8, 2.6, 3.5, 7, 
10, 4.5, 6, 6.5, 5.8, 5.4, 6.2, 8.9, 5.5, 4.8, 3.4, 6.5, 5, 4, 
6.4, 7.3, 4.4, 4.2, 1.7, 5.1, 3.6, 6.4, 3.4, 2.5, 2.6, 2.3, 2.3, 
3.2, 1.6, 1.7, 3.7, 8, 4.4, 3.1, 4.1, 5.9, 2.8, 5, 3.2, 3.7, 
3.4, 1.8, 3.2, 1.2, 4.1, 5.2, 4.5, 4.8, 7.1, 7.3, 4.6, 8.4, 3.4, 
5.2, 6.1, 4.3, 4.5, 4.5, 6.5, 2.8, 6.3, 5.3, 8.2, 3.8, 4.3, 4.2, 
3.4, 5.4, 7.9, 1.2, 1.4, 1.4, 6.6, 6.8, 4.2, 2.9, 3.1, 5.3, 2.6, 
3.2, 2.9, 1.7, 1.9, 1.4, 8, 8, 4, 5, 4.3, 2.9, 6.9, 3, 8.7, 4.5, 
4.2, 6.6, 4.4, 2.7, 4.4, 4.3, 2.8), group = c("Source0", "Source0", 
"Source0", "Source0", "Source0", "Source0", "Source0", "Source0", 
"Source0", "Source0", "Source0", "Source0", "Source0", "Source1", 
"Source1", "Source1", "Source1", "Source1", "Source1", "Source1", 
"Source1", "Source1", "Source1", "Source1", "Source1", "Source1", 
"Source1", "Source1", "Source1", "Source1", "Source1", "Source2", 
"Source2", "Source2", "Source2", "Source2", "Source2", "Source2", 
"Source2", "Source2", "Source2", "Source2", "Source2", "Source2", 
"Source2", "Source2", "Source2", "Source2", "Source2", "Source2", 
"Source2", "Source2", "Source2", "Source2", "Source3", "Source3", 
"Source3", "Source3", "Source3", "Source3", "Source3", "Source3", 
"Source3", "Source3", "Source3", "Source3", "Source3", "Source4", 
"Source4", "Source4", "Source4", "Source4", "Source4", "Source5", 
"Source5", "Source5", "Source5", "Source5", "Source5", "Source5", 
"Source5", "Source5", "Source5", "Source5", "Source6", "Source6", 
"Source6", "Source6", "Source7", "Source7", "Source7", "Source7", 
"Source7", "Source7", "Source7", "Source8", "Source8", "Source8", 
"Source8", "Source8", "Source8", "Source8", "Source8", "Source8", 
"Source8", "Source8", "Source8", "Source9", "Source9", "Source9", 
"Source9", "Source9", "Source9", "Source9", "Source9", "Source10", 
"Source10", "Source10", "Source10", "Source10", "Source10", "Source10", 
"Source10", "Source10")), .Names = c("source", "target", "value", 
"group"), row.names = c(NA, -124L), class = "data.frame")), .Names = c("nodes", 
"links"))

推荐答案

颜色调色板由colourScale参数确定.它应该是一个包含有效D3代码的字符串,以定义调色板.在使用D3v4 +的当前版本的networkD3中,语法d3.scaleOrdinal().range(["#7d3945", "#e0677b", "#244457"])是有效的,尽管可以将其缩短为d3.scaleOrdinal(["#7d3945", "#e0677b", "#244457"]).还有其他可能性,请参见此处.您选择/定义的调色板中的颜色数量必须等于或大于数据中定义的唯一组的总数,否则它将循环回到调色板的开头,以将颜色分配给其他组.数据中定义的第一个组将被分配为调色板中的第一个颜色,依此类推.

The color pallete is determined by the colourScale argument. It should be a string containing valid D3 code to define the palette. In the current version of networkD3, which uses D3v4+, the syntax d3.scaleOrdinal().range(["#7d3945", "#e0677b", "#244457"]) is valid, though it could be shortened to d3.scaleOrdinal(["#7d3945", "#e0677b", "#244457"]). There are other possibilites as well, see here. The number of colors in the palette you choose/define must be equal to or greater than the total number of unique groups defined in your data, otherwise it will loop back to the beginning of your color palette to assign colors to further groups. The first group defined in your data will be assigned the first color in your color palette, and so forth.

NodeGroupLinkGroup参数分别定义NodesLinks数据帧中列的名称,这些列定义每个节点/链接的组值.节点和链接都将根据其组值和根据使用的调色板为其分配的颜色进行着色.

The NodeGroup and LinkGroup parameters define the name of the column in your Nodes and Links data.frames, respectively, that define the group value for each node/link. Both nodes and links will be colored according to their group value and its assigned color based on the color palette being used.

iteration参数设置为0将有效防止放置算法运行,因此将按照原始数据中的顺序对节点进行排序.正如您所指出的那样,这实际上违反了sankeyNetwork的主要目的.

Setting the iteration argument to 0 will effectively prevent the placement algorithm from running, so your nodes will be ordered as they were in the original data. As you've pointed out, this essentially defeats the primary purpose of sankeyNetwork.

使用您发布的数据...

Using the data you posted...

library(networkD3)

colors <- paste(networkD3_data$nodes$colors, collapse = '", "')
colorJS <- paste('d3.scaleOrdinal(["', colors, '"])')

sankeyNetwork(Links = networkD3_data$links, Nodes = networkD3_data$nodes, 
              Source = 'source', Target = 'target', Value = 'value', 
              NodeID = 'name', NodeGroup = "group", LinkGroup = "group",
              colourScale = colorJS,
              iterations = 0)

可以通过在D3调色板中设置RGBA颜色来实现透明度/不透明度,但是您将需要使用十进制RGB表示法(据我所知).您需要将#ff0043之类的内容转换为d3.rgb(255,0,67,0.5)之类的内容,其中最后一个数字是介于0和1之间的数字,用于定义不透明度的级别.例如...

Transparency/opacity can be achieved by setting RGBA colors in the D3 color palette, but you'll need to use the decimal RGB notation (as far as I can tell). You'll want to convert something like #ff0043 into something like d3.rgb(255,0,67,0.5), where the last number is a number between 0 and 1 that defines the level of opacity. For example...

colors <- paste(sapply(networkD3_data$nodes$colors, function(x) { paste0("d3.rgb(", paste(c(col2rgb(x), 0.5), collapse = "," ), ")") }), collapse = ", ")
colorJS <- paste0('d3.scaleOrdinal([', colors, '])')
sankeyNetwork(Links = networkD3_data$links, Nodes = networkD3_data$nodes,
              Source = 'source', Target = 'target', Value = 'value',
              NodeID = 'name', NodeGroup = "group", LinkGroup = "group",
              colourScale = colorJS,
              iterations = 0)

这篇关于使用用户定义的颜色修改networkD3 sankey图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆