Gluing Graphs Together: Switch ("toggle") Between Graphs in r/plotly

I am working with the R programming language. I am trying to replicate this tutorial over here for my own data: https://plotly.com/r/dropdowns/

I created some fake data and made 4 plots:

#load libraries 

library(plotly)
library(MASS)
library(dplyr)


# create data

x <- sample( LETTERS[1:4], 731, replace=TRUE, prob=c(0.25, 0.25, 0.25, 0.25) )
y <- rnorm(731,10,10)
z <- rnorm(731,5,5)
date= seq(as.Date("2014/1/1"), as.Date("2016/1/1"),by="day")
    
    df <- data.frame(x,y, z, date)
df$x = as.factor(df$x)



# plot 1 : time series

 aggregate = df %>%
        mutate(date = as.Date(date)) %>%
        group_by(month = format(date, "%Y-%m")) %>%
        summarise( mean = mean(y))

ts_1 <- ggplot(aggregate) + geom_line(aes(x = month, y = mean, group = 1)) +  theme(axis.text.x = element_text(angle = 90)) + ggtitle("time series 1")

plot_1 = ggplotly(ts_1)



#plot 2 : box plot

plot_2 <- plot_ly(df, y = ~y, color = ~x, type = "box") %>% layout(title = "boxplot")



#plot 3, 4 : scatter plots

df_1 <- df[which(df$x == "A"),]
df_2 <- df[which(df$x == "B"),]


plot_3 <- plot_ly( data = df_1, type = "scatter", mode = "markers", x = ~ y, y = ~z) %>% layout(title = "graph 3")

plot_4 <- plot_ly( data = df_2, type = "scatter", mode = "markers", x = ~ y, y = ~z) %>% layout(title = "graph 4")

Once these 4 plots have been created, I know how to save them together:

sub = subplot(plot_1, plot_2, plot_3, plot_4, nrows = 2)
#view result
sub

Now what I am trying to do, is have the user "toggle" (switch) between these graphs :

I learned how to "glue" similar graphs together (e.g. 4 scatter plots). Now, I am trying to do so with different graphs (2 scatter plots, 1 time series and 1 box plot). I tried to adapt the code from the previous post to suit my example:

fig <- df %>% 
  add_trace(name = "A", plot_1) %>% 
  add_trace (name = "B" , df, y = ~y, color = ~x, type = "box") %>% layout(title = "boxplot")
  add_trace (name = "C" , data = df_1, type = "scatter", mode = "markers", x = ~ y, y = ~z) %>% layout(title = "graph 3") %>%
  add_trace( name = "D", data = df_2, type = "scatter", mode = "markers", x = ~ y, y = ~z) %>% layout(title = "graph 4") %>% 
  layout(xaxis = list(domain = c(0.1, 1)),
         yaxis = list(title = "y"),
         updatemenus = list(
           list(
             y = 0.7,
             buttons = list(
               list(method = "restyle",
                    args = list("visible", list(TRUE, FALSE, FALSE, FALSE)),
                    label = "A"),
               list(method = "restyle",
                    args = list("visible", list(FALSE, TRUE, FALSE, FALSE)),
                    label = "B"),
               list(method = "restyle",
                    args = list("visible", list(FALSE, FALSE, TRUE, FALSE)),
                    label = "C"),
               list(method = "restyle",
                    args = list("visible", list(FALSE, FALSE, FALSE, TRUE)),
                    label = "D")))))

But this produces the following errors:

Error: $ operator is invalid for atomic vectors
Error in add_data(p, data) : argument "p" is missing, with no default

Can someone please show me if it is possible to fix this problem? Instead of using the "add_trace" approach, is it somehow possible to individually call each plotly graph object by its name (e.g. subplot(plot_1, plot_2, plot_3, plot_4, nrows = 2) ), "glue" all the graphs together, and then add a "toggle button" that lets the user switch between them?

Thanks

hi there,
as far as i can see, you need to use the same data.frame as source for your plots.
You need to use the following syntax, like this

fig <- fig %>% add_trace(...

thank you for your reply. i have been working on this problem for a few days now and have been really struggling. if possible, could you please show me how to fully correct this code? Here is a similar question on stackoverflow: https://stackoverflow.com/questions/66161597/gluing-graphs-together-trouble-with-traces-operator-is-invalid-for-atomic

thank you so much for all your help

i know its a bit buggy, but this should lead you in the right direction

fig = plot_ly()
fig = fig %>% add_trace(data = df %>%
                          mutate(date = as.Date(date)) %>%
                          group_by(month = format(date, "%Y-%m")) %>%
                          summarise( mean = mean(y)), type = 'scatter', mode = 'lines', x= ~month, y= ~mean,
                        name = "timeseries")
fig = fig %>%  add_trace(data = df[which(df$x == "A"),], y = ~y, color = ~x, 
                         type = "box", name = "boxplot") 
fig = fig %>%  add_trace( data = df[which(df$x == "B"),], 
                          type = "scatter", mode = "markers", x = ~ y, y = ~z, 
                          name= "graph2")
fig = fig %>%  add_trace(data = df[which(df$x == "A"),], y = ~y, color = ~x, 
                         type = "box", name = "boxplot2") 


fig %>% layout(xaxis = list(domain = c(0.1, 1)),
               yaxis = list(title = "y"),
               updatemenus = list(
                 list(
                   y = 0.7,
                   buttons = list(
                     list(method = "restyle",
                          args = list("visible", list(TRUE, FALSE, FALSE, FALSE)),
                          label = "A"),
                     list(method = "restyle",
                          args = list("visible", list(FALSE, TRUE, FALSE, FALSE)),
                          label = "B"),
                     list(method = "restyle",
                          args = list("visible", list(FALSE, FALSE, TRUE, FALSE)),
                          label = "C"),
                     list(method = "restyle",
                          args = list("visible", list(FALSE, FALSE, FALSE, TRUE)),
                          label = "D")))))

thank you so much for your reply! this is really good! I will try to keep working on this and fix the axis . thanks again for everything

you're welcome!
this could be helpful for styling axes:

For those interested: here is my answer on this.

This topic was automatically closed 21 days after the last reply. New replies are no longer allowed.

If you have a query related to it or one of the replies, start a new topic and refer back with a link.