4

Picking up on this question, I'm trying to assign a set of colours to nodes, and hopefully links with the gradient mode, in a Sankey chart using GoogleVis package in R. The issue is that I have the same categories in each of the 3 sets of nodes, and I'm having trouble getting it to cooperate.

datSK <- data.frame(From=c(rep("A1",3), rep("B1", 3), rep("C1", 3), rep("A2", 3), rep("B2", 3), rep("C2",3)), 
                To=c(rep(c("A2", "B2", "C2"), 3), rep(c("A3", "B3", "C3"), 3)),
                Weight=c(5,7,6,2,9,4,3,4,5))

I want nodes A, B, C, which appear in 3 different parts of the chart to have the same colors (respectively blue, orange, green).

plot(gvisSankey(datSK, from="From", 
       to="To", weight="Weight",
       options=list(sankey="{
                    link: { colorMode: 'gradient', colors: ['blue', 'orange', 'green']}, 
                    node: { colors: ['blue', 'orange', 'green']}}")))

Unfortunately, I can't figure out how the colours are being assigned.

Community
  • 1
  • 1
Phil
  • 7,287
  • 3
  • 36
  • 66

2 Answers2

4

It has been a year, I do not know whether you still need the answer or not but this is what I found:

plot(gvisSankey(datSK, from="From", 
       to="To", weight="Weight",
       options=list(sankey="{
                    link: { colorMode: 'gradient'}, 
                    node: { colors: ['blue', 'blue', 'orange',
                                     'green','orange', 'green',
                                     'blue','orange','green']}
                             }")))

Google's Sankey Chart will assign the color based on the appearance order of the nodes. Here is how I decide the appearance order of the node. Basically I create a string of a list of node connections, split them, and extract the unique nodes, then assign the colors.

# Create a stringlist of node pairs
nodestringlist <- paste(datSK$From,datSK$To, collapse=' ')

# Split them up
nodestringvector <- strsplit(nodestringlist, split =' ')

# Find the unique nodes in order they appear
node_order <- unique(nodestringvector[[1]])
#output: "A1" "A2" "B2" "C2" "B1" "C1" "A3" "B3" "C3"

Is this what you want?

addicted
  • 2,901
  • 3
  • 28
  • 49
  • 1
    I can't remember now. :) but it looks like @svenhalvorson needed an answer as well so hopefully it will help him. Also, I think there's a ggplot version of a sankey chart that will eventually be available through `ggforce`. – Phil Sep 12 '17 at 14:28
  • Thanks for marking my answer. That ggplot's sankey sounds like a great idea. I'll take a look on it too. – addicted Sep 13 '17 at 02:02
1

I would like to add another solution.

# install.packages("googleVis")
library(googleVis)

# Dataframe from your example
datSK <- data.frame(
  From = c(rep("A1", 3),
           rep("B1", 3),
           rep("C1", 3),
           rep("A2", 3),
           rep("B2", 3),
           rep("C2", 3)),
  To = c(rep(c("A2", "B2", "C2"), 3),
         rep(c("A3", "B3", "C3"), 3)),
  Weight = c(5, 7, 6, 2 ,9, 4, 3, 4, 5))

# Costumize the color of nodes:
val_dat <- c()
for (i in 1:nrow(datSK)) {
  val_dat <- c(val_dat, as.character(datSK$From[i]),
               as.character(datSK$To[i]))
}

node_color <- sapply(unique(val_dat), function(set_color) {
  if (grepl('A', set_color)) return('blue')
  if (grepl('B', set_color)) return('orange')
  if (grepl('C', set_color)) return('green')
})

# Create the plot
sankey_plot <- gvisSankey(
  datSK,
  from = "From",
  to = "To",
  weight = "Weight",
  options = list(
    sankey = paste0("{ link: { colorMode: 'gradient'},
      node: {
        colors: ['",paste(node_color, collapse="','"), "']
           }
      }")))

# Show the plot
plot(sankey_plot)

Sankey Plot

Kpamungkas
  • 41
  • 4