4

I'm trying to animate a plot for the following data frame:

df <- data.frame(
  Creative <- c("BG", "HB", "OV3", "OV4", "TI", 
                "BG", "HB", "IW", "OV3", "OV4", "TI", 
                "Women30", "BG", "HB", "IW", "LA", 
                "OP3", "OV4", "TI", "BG", "HB", "IW", 
                "OV3", "OV4", "TI", "TM", "BG", "HB", "IW",
                "OV3", "OV4", "TI", "BG", "HB", "IW", "OV3", 
                "OV4", "TI", "Hb", "IW", "OV3", "OV4", "TI", "TM"),
  Spend <- c("10000", "3000", "4000", "16000", "10000", "10000", "7000", "5000", "10000", 
             "20000", "14000", "2000", "11000", "7000", "6000", "3000", "12000", "20000", "12000",
             "8000", "14000", "7000", "8100", "15505", "10075.5", "2000.62", "7000.14", "10531.08", "14831.03", "3481.73",
             "5031.93", "14600.53", "8000.12", "15000.08", "29000.79", "5000.65", "40000.04", "14000.75", "7000.56", "23000.64", "10000.55", 
             "12000.56", "11353.7", "8000.65"),
  Profitability <- c("0.18911111", "0.09", "-0.04", "-0.08", "0.01799735", "0.05067851", "0.29", "0.11817021", "-0.03682584", "-0.16",
                     "-0.11639344", "-0.41", "0.07035971", "0.34", "0.31012579", "-0.21522822", "-0.03106155", "-0.19", "-0.12512605",
                     "-0.05311224", "0.18", "-0.09731278", "-0.20401676", "-0.05457789", "-0.03661734", "-0.17182222", "-0.068125",
                     "0.14", "0.24371284", "-0.02686726", "-0.08510383", "-0.09900938", "-0.09861953", "0.05", "0.22176382", "0.07751868",
                     "0.05005076", "-0.13422111", "-0.17", "0.22727374", "0.10032397", "0.06960388", "-0.28228181", "0.05402597"),
  Date <- c("09/27/19", "09/27/19", "09/27/19", "09/27/19", "09/27/19", "10/01/19", "10/01/19", "10/01/19", "10/01/19",
            "10/01/19", "10/01/19", "10/01/19", "10/02/19", "10/02/19", "10/02/19", "10/02/19", "10/02/19", "10/02/19", 
            "10/02/19", "10/08/19", "10/08/19", "10/08/19", "10/08/19", "10/08/19", "10/08/19", "10/08/19", "10/10/19", 
            "10/10/19", "10/10/19", "10/10/19", "10/10/19", "10/10/19", "10/11/19", "10/11/19", "10/11/19", "10/11/19", 
            "10/11/19", "10/11/19", "10/14/19", "10/14/19", "10/14/19", "10/14/19", "10/14/19", "10/14/19")
)

colnames(df) <- c("Creative", "Spend", "Profitability", "Date")
df$Date <- as.Date(df$Date, format = "%m/%d/%y")
df[, 2:3] <- lapply(df[, 2:3], function(x) as.numeric(as.character(x)))

I'm graphing Spend on the x-axis and Profitability on the y-axis, and I want each creative to be represented as a scatter point. The animation would be over time (iterating through the dates). This is the code for my animation so far:

plot <- df %>%
  plot_ly(
    x = ~Spend,
    y = ~Profitability,
    frame = ~Date,
    color = ~Creative,
    ids = ~Creative,
    text = ~Creative,
    type = 'scatter',
    marker = list(size = 15),
    mode = 'markers+text',
    textposition='bottom',
    showlegend = F
  )

plot_anim <- plot %>%  animation_opts(
  1000, easing = "cubic-in-out", transition = "1000", redraw = FALSE, mode = "afterall"
) %>% 
  animation_button(
    x = 1, xanchor = "right", y = 0, yanchor = "bottom"
  ) %>%
  animation_slider(
    currentvalue = list(prefix = "DATE ", font = list(color="red"))
  )

The issue I'm facing is related to the fact that not all creatives are present on every date (because they don't spend on that day). In this case, Plotly makes the scatter points that are present on one day and not on the next to fade away, but this makes the graphic confusing because it distracts from the animation of the scatter points that are actually transitioning from one point to another on the graph. Is there a way to change this so that a scatter point simply disappears if it isn't present on the next day, while other points can have a normal continuous transition (this appears to be the default method on ggplot but not on plotly).

For reference, this is what I was trying to graph in ggplot (couldn't directly attach the gif due to low status). With ggplot, you can see that points simply dissapear instead of fading away when they aren't present in the next time step: ggplot gif

Thank you!

2 Answers2

0

You can just remove the ID attribute from plotly(). Therefore plotly will stop looking for the exact value of creative for start and end of the date.

plot <- df %>%
   plot_ly(
    x = ~Spend,
    y = ~Profitability,
    frame = ~Date,
    color = ~Creative,
    text = ~Creative,
    type = 'scatter',
    marker = list(size = 15),
    mode = 'markers+text',
    textposition='bottom',
    showlegend = F
  )



plot_anim <- plot %>%  animation_opts(
  1000, easing = "linear-in", transition = "1000", redraw = FALSE, mode = "afterall"
) %>% 
  animation_button(
    x = 1, xanchor = "right", y = 0, yanchor = "bottom"
  ) %>%
  animation_slider(
    currentvalue = list(prefix = "DATE ", font = list(color="red"))
  )

plot_anim

I hope that helps!!!!

AnandOCF
  • 392
  • 2
  • 9
0

As you said the problem is that your data frame is not complete. Therefore you should have seen an error message like:

In p$x$data[firstFrame] <- p$x$frames[[1]]$data ...

You could complete the data frame by

dfa <- df %>% complete(Date, nesting(Creative), fill = list(Spend = 0, Profitability =-0.6))

This will complete the data frame by adding rows at which Date / Creative combination data are missing. I have given those added rows the data Spend = 0 and Profitability = 0. By setting the yaxis limits to -0.5 to +0.5 you kind of store those points in the left bottom corner of the plot from where they will move into the plot. I have therefore added a layout(yaxis = list(range = c(-0.5, 0.5))).

Also a style(textposition = 'bottom') was added which makes sure that the text labels show up right.

The complete code is:

dfa <- df %>% complete(Date, nesting(Creative),fill = list(Spend = 0, Profitability =-0.6))
plot <- dfa %>%
  plot_ly(
    x = ~Spend,
    y = ~Profitability,
    frame = ~Date,
    color = ~Creative,
    ids = ~Creative,
    text = ~Creative,
    type = 'scatter',
    marker = list(size = 15),
    mode = 'markers+text',
    #textposition='bottom',
    showlegend = F
  )

plot_anim <- plot %>%  animation_opts(
  1000, easing = "cubic-in-out", transition = "1000", redraw = TRUE, mode = "afterall"
) %>% 
  animation_button(
    x = 1, xanchor = "right", y = 0, yanchor = "bottom"
  ) %>%
  animation_slider(
    currentvalue = list(prefix = "DATE ", font = list(color="red"))
  ) %>% 
  style(textposition = 'bottom') %>% 
  layout(yaxis = list(range = c(-0.5, 0.5)))

plot_anim

Try it out, You will see that the animation starts with 5 dots. Some dots are then entering from the left bottom corner into the plot.

I hope that is what you wanted to see.

MarBlo
  • 4,195
  • 1
  • 13
  • 27