7

How can node and link colors be changed in R googleVis sankey chart? And link having the same color as its originating node?

library(googleVis)
datSK <- data.frame(From=c(rep("A",3), rep("B", 3)),
                To=c(rep(c("X", "Y", "Z"),2)),
                Weight=c(5,7,6,2,9,4))

Sankey <- gvisSankey(datSK, from="From", to="To", weight="Weight",
                 options=list(
                   sankey="{link: {color: { fill: '#d799ae' } },
                        node: { color: { fill: '#a61d4c' },
                        label: { color: '#871b47' } }}"))
plot(Sankey)
Vadym B.
  • 681
  • 7
  • 21
santoku
  • 3,297
  • 7
  • 48
  • 76

3 Answers3

11

As soon as you have to color links from 2 originated nodes you'll need 2 colors for links. Also you have 5 nodes in total, so you'll need 5 colors for them.

Lets create 2 arrays in JSON format with colors for nodes and links

colors_link <- c('green', 'blue')
colors_link_array <- paste0("[", paste0("'", colors_link,"'", collapse = ','), "]")

colors_node <- c('yellow', 'lightblue', 'red', 'black', 'brown')
colors_node_array <- paste0("[", paste0("'", colors_node,"'", collapse = ','), "]")

Next, insert that array into options:

opts <- paste0("{
        link: { colorMode: 'source',
                colors: ", colors_link_array ," },
        node: { colors: ", colors_node_array ," }
      }" )

And, finally plot graph:

plot( gvisSankey(datSK, from="From", to="To", weight="Weight",
                     options=list(
                       sankey=opts)))

enter image description here

Note, that in options colorMode is set to 'source' which means you would like to color links from originated nodes. Alternatively, set 'target' to color links for destinated nodes

EDIT: add description for multilevel sankeys

It is a bit tricky to find how to assign colors for multilevel sankeys.

We need to create other dateframe:

datSK <- data.frame(From=c(rep("A",3), rep("B", 3), rep(c("X", "Y", "Z"), 2 )),
                To=c(rep(c("X", "Y", "Z"),2), rep("M", 3), rep("N", 3)),
                Weight=c(5,7,6,2,9,4,3,4,5,6, 4,8))

Here we have to change only arrays of colors. Command to built plot is the same Let's assume we want these colors for the nodes and links :

colors_link <- c('green', 'blue', 'yellow', 'brown', 'red')
colors_link_array <- paste0("[", paste0("'", colors_link,"'", collapse = ','), "]")

colors_node <- c('yellow', 'lightblue', 'red', 'black', 'brown', 'green', 'brown')
colors_node_array <- paste0("[", paste0("'", colors_node,"'", collapse = ','), "]")

Result would be :

enter image description here

The most trickiest part is to understand how these colors are assigned:

  1. Links are assigned in the order they appear in dataset (row_wise)

enter image description here

  1. For the nodes colors are assigned in the order plot is built.

    • From A to X, Y, Z - green
    • From X to M, N - blue
    • From Y to M, N - yellow
    • From Z to M, N - brown
    • From B to X, Y, Z - red

More detailed information on how to format sankey diagram : https://developers.google.com/chart/interactive/docs/gallery/sankey

Vadym B.
  • 681
  • 7
  • 21
  • Could you extend your answer for [Multilevel Sankeys](https://developers.google.com/chart/interactive/docs/gallery/sankey#multilevel-sankeys)? – zx8754 Apr 18 '16 at 12:53
  • Is it possible to have two different colors coming out of one node? In other words, can colors be set without using "source" or "target" as colorMode? See: https://stackoverflow.com/questions/45291340/how-to-color-two-links-coming-out-of-the-same-node-or-going-to-the-same-node-w – Raul Torres Jul 27 '17 at 16:22
4

I know this is older but in case anyone else is ever stuck on this - I figured out how to make the proper order and generate a string of color nodes so you can have custom colors for certain labels. Shout out to @vadym-b for the data and explaining about the order. Check it out:

#convert to list combined of source and target for color order
# edges is a dataframe from @vadym-b's answer above
edges <- data.frame(From=c(rep("A",3), rep("B", 3), rep(c("X", "Y", "Z"), 2 )),
                    To=c(rep(c("X", "Y", "Z"),2), rep("M", 3), rep("N", 3)),
                    Weight=c(5,7,6,2,9,4,3,4,5,6, 4,8))

#we have to make the order right - you need a list
# that is a combination of From, To, From, To, From, To
nc.df <- c()
for (i in 1:nrow(edges)) {
  nc.df <- c(nc.df, as.character(edges$From[i]), as.character(edges$To[i]))
}

#the actualy parsing - get the unique list and return
# colors based on what the source or target value is
nodeColor <- sapply(unique(nc.df), function(r) {
  if (grepl('A',r)) return('red')
  if (grepl('B',r)) return('red')
  if (grepl('Z',r)) return('green')
  if (grepl('X',r)) return('green')
  if (grepl('Y',r)) return('purple')
  if (grepl('M',r)) return('blue')
  if (grepl('N',r)) return('blue')
  #return a default color if you like
  return('black')
})

#make a sankey
library(googleVis)

# put the color list in a collapsed string
sankey <- gvisSankey(
  edges, 
  chartid = 'Sankey', 
  from="From", 
  to="To", 
  weight="Weight", 
  options=list(
    sankey = paste0("{
      iterations: 0,
      link: {
        colorMode: 'gradient'
      },
      node: {
        colors: ['",paste(nodeColor,collapse="','"),"']
      }
    }")
  )
)

plot(sankey)

Sankey with custom colors

Michael Tallino
  • 821
  • 4
  • 16
  • I absolutely love this! Question though. What if you wanted A -> X to be one color and A -> Y to be another? how would the code change? – tangerine7199 Jan 16 '19 at 14:23
  • @walker I think you could add another `for` loop but have it paste the `edges$From` and `edges$To` together as a single string so it's like `c('AZ','BY',...)`, then `sapply` on that vector with `grepl` calls that look for that for -> to link.... I haven't tried this though – Michael Tallino Jan 17 '19 at 15:34
1

I have put on github a piece of code that does that.

#TOPLOTS[,1] = from ; TOPLOTS[,1] = to
names_pahtwayorder<-unlist(data.frame(t(TOPLOTs[,1:2])))
names_pahtwayorder<-names_pahtwayorder[!duplicated(names_pahtwayorder)]
names(names_pahtwayorder)<-NULL; names_pahtwayorder

https://github.com/SkanderMulder/ExtractIPA/blob/master/functionSankey.r

STM
  • 36
  • 3