1

Important clarification: I am using an older, non-CRAN branch of networkD3 forked by Florian Breitwieser fbreitwieser/networkD3/tree/add_zoom. Florian's branch added zooming capabilities to Sankey graphs, but was not merged into the CRAN package. Since that particular branch has not been updated since 2016, the syntax here differs than what should be used with the current (as of 2018-02-15) CRAN release.


I am attempting to apply custom colors to a networkD3 sankeyGraph().

I am attempting to reproduce Example #1 from https://www.r-graph-gallery.com/322-custom-colours-in-sankey-diagram/ .

I'm guessing there may have been a package update or two since that example was originally posted, any ideas on what might need to change here?

(Almost verbatim) Code From Example

(The only non-formatting change I made was to load magrittr directly instead of piling on a dozen tidyverse packages just for the pipe)

# Library
library(networkD3)
#library(tidyverse)
library(magrittr)

# Make a connection data frame
links=data.frame(source=c("group_A","group_A", "group_B", "group_C", "group_C", "group_E"),
                 target=c("group_C","group_D", "group_E", "group_F", "group_G", "group_H"),
                 value=c(2,3, 2, 3, 1, 3))

# From these flows we need to create a node data frame: it lists every entities involved in the flow
nodes=data.frame(name=c(as.character(links$source), as.character(links$target)) %>% unique())
links$IDsource=match(links$source, nodes$name)-1 
links$IDtarget=match(links$target, nodes$name)-1

# prepare color scale: I give one specific color for each node.
my_color <- 'd3.scaleOrdinal() .domain(["group_A", "group_B","group_C", "group_D", "group_E", "group_F", "group_G", "group_H"]) .range(["blue", "blue" , "blue", "red", "red", "yellow", "purple", "purple"])'

# Make the Network. I call my colour scale with the colourScale argument
sankeyNetwork(Links = links,
              Nodes = nodes,
              Source = "IDsource",
              Target = "IDtarget",
              Value = "value",
              colourScale= my_color,
              NodeID = "name")

What was supposed to come out:

desired output

What I get out:

Current Output

Commenting out colourScale shows everything else is working.

sankeyNetwork(Links = links,
              Nodes = nodes,
              Source = "IDsource",
              Target = "IDtarget",
              Value = "value",
              # colourScale= my_color,
              NodeID = "name")

partial

Some things I tried:

The Q&A Modify networkD3 sankey plot with user-defined colors seemed promising, but when I run what was marked as an accepted answer I get a blank output again.

How to color groups in networkD3's sankeyNetwork? also seemed very promising since it had an answer from a package contributor(@cjyetman), and while I was able to reproduce his minimal example, I was unsuccessful in adding a custom color mapping.

Own colour range for Sankey Diagram with networkD3 package in R yet again seemed to cover what the appropriate syntax would be, but I struck out again on applying the advice there to this problem.

Matt Summersgill
  • 4,054
  • 18
  • 47

1 Answers1

0

Important clarification: I am using an older, non-CRAN branch of networkD3 forked by Florian Breitwieser fbreitwieser/networkD3/tree/add_zoom. Florian's branch added zooming capabilities to Sankey graphs, but was not merged into the CRAN package. Since that particular branch has not been updated since 2016, the syntax here differs than what should be used with the current (as of 2018-02-15) CRAN release.

Welp, finally got it based on Sankey Diagram with R library networkD3 does not show colors

The proper format for this usage is as follows.

my_color <- 'd3.scale.category10().range(["blue", "blue" , "blue", "red", "red", "yellow", "purple", "purple"]).domain(["group_A", "group_B","group_C", "group_D", "group_E", "group_F", "group_G", "group_H"])'

Another issue I finally figured out: group names in the domain can not have spaces!

This would work:

'd3.scale.category10().range(["blue", "red"]).domain(["group_A", "group_B"])'

This would not!

'd3.scale.category10().range(["blue", "red"]).domain(["group A", "group B"])'
Matt Summersgill
  • 4,054
  • 18
  • 47
  • 1
    You’re probably using an old version of `networkD3`... that looks like old d3v3 syntax. – CJ Yetman Feb 14 '18 at 21:39
  • Also, you need to set the NodeGroup parameter, no? – CJ Yetman Feb 14 '18 at 21:44
  • @CJYetman I am using a branch to add zooming functionality to Sankey diagrams -- [ "add zoom" Florian Breitwieser on github](https://github.com/fbreitwieser/networkD3/tree/add_zoom) . Perhaps that's the source of my confusion? Based on that, two questions. 1: Is it possible to zoom Sankey diagrams in the main release? it looks like that PR didn't get merged. 2: Do you think it would be in the best interest of the community for me to delete this question? I don't want to confuse other people looking for answers if this solution is incorrect in the main release. – Matt Summersgill Feb 14 '18 at 21:50
  • 1
    Maybe it would be good to clarify in your “answer” that it’s only relevant to old versions of networkD3. Surely you’re not the only one using an old version, or a branch based on an old version. – CJ Yetman Feb 14 '18 at 22:40
  • I don’t know about zooming a sankeyNetwork. I haven’t worked much on the side of the package. – CJ Yetman Feb 14 '18 at 22:51
  • Thanks for the clarification at the top. Also good to know... the vector containing the group names must be a character vector, numeric vector does not work (unless coerced to character first). – CJ Yetman Feb 18 '18 at 09:15