Jonas Schnidrig
Jonas Schnidrig

Reputation: 149

Plotly Sankey diagram animated frame same for different steps

I have an issue when trying to use the animation of Sankeys through different frames. I get for both steps the same Sankey, despite having different values in the data frame.

[![Frame 2020][1]][1] [![Frame 2021][2]][2]

The code to reproduce the error is here below

  output <- c("A", "B", "C", "D", "E")
  input <- c("B", "B", "G", "E", "G")
  value <- c(1, 2, 1, 3, 2)
  year <- c(2020, 2020, 2021, 2021, 2021)
  color <- c("red", "blue", "green", "yellow", "orange")

  # Combine the vectors into a dataframe
  df <- data.frame(output, input, value, year, color)

  all_et <- as.list(unique(c(df$input, df$output)))
  source <- as.list(match(as.list(df$input), all_et) - 1)
  target <- as.list(match(as.list(df$output), all_et) - 1)

  plot_ly(
    type = "sankey",
    orientation = "h",
    valuesuffix = "TWh",

    node = list(
      pad = 10,
      thickness = 20,
      group = 1,
      line = list(width = 0),
      label = all_et,
      color = 'lightgray'
    ),
    link = list(
      source = source,
      target = target,
      line = list(color = "black", width = 0.01),
      value = as.list(df$value),
      color = as.list(df$color) #, # needs further development by plot_ly: waiting for new release js 2020.04.29
    ),
    frame = ~df$year
  )

Any idea how to solve this issue?

Thank you [1]: https://i.sstatic.net/CIiQv.png [2]: https://i.sstatic.net/LNnfL.png

Upvotes: 0

Views: 202

Answers (2)

Jonas Schnidrig
Jonas Schnidrig

Reputation: 149

Based on the answer by Julian Selke, the solution is to transform the string inputs in numbers, adapting the code such as

output <- c("A", "B", "C", "C", "B")
input <- c("B", "C", "A", "B", "A")
year <- c(2020, 2020, 2021, 2021, 2021)
color <- c("red", "blue", "green", "yellow", "orange")

# Combine the vectors into a dataframe
df <- data.frame(output, input, value, year, color)

  all_et <- unique(c(df$input, df$output))
  source <- match(as.list(df$input), all_et) - 1
  target <- match(as.list(df$output), all_et) - 1

plot_ly(
  type = "sankey",
  orientation = "h",
  valuesuffix = "TWh",

  node = list(
    pad = 10,
    thickness = 20,
    group = 1,
    line = list(width = 0),
    label = all_et,
    color = 'lightgray'
  ),
  link = list(
    source = source,
    target = target,
    line = list(color = "black", width = 0.01),
    value = df$value,
    color = df$color
  ),
  frame = df$year
)

Upvotes: 0

Julian Selke
Julian Selke

Reputation: 298

The links are expected to be numeric representations of source and target starting at index 0 (i.e. "A" = 0, "B" = 1, etc.).

Here is an adaption of your code that meets these requirements:

output <- c(0, 1, 2, 3, 4)
input <- c(1, 1, 5, 4, 5)
value <- c(1, 2, 1, 3, 2)
year <- c(2020, 2020, 2021, 2021, 2021)
color <- c("red", "blue", "green", "yellow", "orange")

# Combine the vectors into a dataframe
df <- data.frame(output, input, value, year, color)

plot_ly(
  type = "sankey",
  orientation = "h",
  valuesuffix = "TWh",
  
  node = list(
    pad = 10,
    thickness = 20,
    group = 1,
    line = list(width = 0),
    label = c("A", "B", "C", "D", "E", "G"),
    color = 'lightgray'
  ),
  link = list(
    source = df$input,
    target = df$output,
    line = list(color = "black", width = 0.01),
    value = df$value,
    color = df$color
  ),
  frame = df$year
)

Upvotes: 1

Related Questions