Search code examples
rplotlysankey-diagram

R plotly - sankey chart not returned


I am running below code in RStudio, and want to create sankey chart with plotly. code runs without error. but the sankey chart is not displayed. what's wrong here?

library("plotly")
a = read.csv('cleanSankey.csv', header=TRUE, sep=',')
node_names <- unique(c(as.character(a$source), as.character(a$target)))
nodes <- data.frame(name = node_names)
links <- data.frame(source = match(a$source, node_names) - 1,
                    target = match(a$target, node_names) - 1,
                    value = a$value)

nodes_with_position <- data.frame(
  "id" = names,
  "label" = node_names,
  "x" = c(0, 0.1, 0.2, 0.3,0.4,0.5,0.6,0.7),
  "y" = c(0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7)
)

#Plot
plot_ly(type='sankey',
        orientation = "h",
        
        node = list(
          label = node_names,
          x = nodes_with_position$x,
          y = nodes_with_position$y,
          color = "grey",
          pad = 15,
          thinkness = 20,
          line = list(color = "grey", width = 0.5)),
 
         link = list(
           source = links$source,
           target = links$target,
           value = links$value))

sankey is plotted , but and nodes for second layer goes to last layer. How to fix the node position?


Solution

  • You'll need to define the node position by setting the arrangement argument to stop plotly from automatically justifying the position.

    This requires some finessing as you need to specify the coordinates of the nodes. You can find more details here: https://plotly.com/python/sankey-diagram/#define-node-position

    Code

    library(plotly)
    
    a <- read.csv("~/cleanSankey.csv")
    
    node_names <- unique(c(as.character(a$source), as.character(a$target)))
    
    # added id column for clarity, but it's likely not needed
    nodes <- data.frame(
      id = 0:(length(node_names)-1),
      name = node_names
    )
    
    links <- data.frame(
      source = match(a$source, node_names) - 1,
      target = match(a$target, node_names) - 1,
      value = a$value
    )
    
    # set the coordinates of the nodes
    nodes$x <- c(0, 1, 0.5)
    nodes$y <- c(0, 0.5, 1)
    
    # plot - note the `arrangement="snap"` argument
    plot_ly(
      type='sankey',
      orientation = "h",
      arrangement="snap", # can also change this to 'fixed'
      node = list(
        label = nodes$name,
        x = nodes$x,
        y = nodes$y,
        color = "grey",
        pad = 15,
        thinkness = 20,
        line = list(color = "grey", width = 0.5)
      ),
      link = list(
        source = links$source,
        target = links$target,
        value = links$value
      )
    )
    

    Plot output with arrangement="snap":

    Sankey plot with arrangement set to "snap"