Plotly R : Modify several attributes from a single restyle button

Hello dear community :slight_smile:

I’m trying to implement a quite “simple” task:
I am trying to modify several data attributes of my graph from a single “custom button” click.

After quite many researches, trials and kind of reverse engineering, I’m still unable to achieve this behavior.

More precisely, I do successfully pass 2 arguments to the “update” method, but I am still struggling to pass a 2nd args to the restyle method.

Neither the basic documentation for the “updatemenus” usage with simples examples, nor the detailed documentation (https://plotly.com/r/reference/#layout-updatemenus) provide and explicit solution to this problem (or at least I cannot find it).

Some topics related to my question are open but are not successfully answered ([https://stackoverflow.com/questions/50841935/multiple-changes-to-data-with-buttons-in-plotly] or also [R: plotly multiple args in updatemenus with same lable] ), to which I am eager to finally find a solution :slight_smile:

I even found a solution… for the python version : [Dropdown with multiple attribute changes] , that I am unable to successfully implement from R.

Here is a Minimal Working Exemple to illustrate the problematic:

suppressMessages(library(plotly))

myData <-  data.frame ("X"=1:10, "Y1"=runif(10), "Y2"=runif(10))

fig <-  plot_ly( data=myData, type = 'scatter', mode = 'line', y = myData$Y1, x = myData$X)

fig <-  layout ( fig, title = "My MWE",
                updatemenus = list(
                                                
                    ## This one works like a charm.
                    list( type="buttons", y = 0.9,
                         buttons = list(
                             list(method = "restyle", args = list( list(mode = "line")),  label = "0 - [Restyle] 1 attribute : mode = line.") , # One way to do it.
                             list(method = "restyle", args = list("mode", "markers"),  label = "1 - [Restyle] 1 attribute : mode = markers.") # Another way of doing it.
                         )
                         ),

                    ## This one works like a charm.
                    list( type="buttons", y = 0.8,
                         buttons = list(
                             list(method = "restyle", args = list( list (y = list(myData$Y1))),  label = "0 - [Restyle] 1 attribute : y = Y1."),
                             list(method = "restyle", args = list("y", list(myData$Y2)),  label = "1 - [Restyle] 1 attribute : y = Y2.")
                         )
                         ),
                    
                    ## This one works like a charm.
                    list( type="buttons", y = 0.7,
                         buttons = list(
                             list(method = "update",
                                  args = list(list(visible = TRUE), list(title = "My MWE")),
                                  label = "0 - [Update] Modify 2 attributes: Visible & Title."),
                             list(method = "update",
                                  args = list(list(visible = FALSE), list(title = "Disapeared!")),
                                  label = "1 - [Update] Modify 2 attributes: Visible & Title.")
                         )
                         ),
                          
                     ## This one apply the first argument but not the second.
                    list( type="buttons", y = 0.3,
                         buttons = list(
                             list(method = "restyle",
                                  args = list( list( y = list(myData$Y1) ), list( mode = "line")),
                                  label = "0 - Modify 2 attributes via restyle: y=Y1; mode=line [Attempt A]"),
                             list(method = "restyle",
                                  args = list( list( y = list(myData$Y2) ), list( mode = "markers")),
                                  label = "1 - Modify 2 attributes via restyle: y=Y2; mode=markers [Attempt A]")
                         )
                         ),

                    ## This one apply the first argument but not the second.
                    list( type="buttons", y = 0.2,
                         buttons = list(
                             list(method = "restyle",
                                  args = list("y", list(myData$Y1), "mode", "line"),
                                  label = "0 - Modify 2 attributes via restyle: y=Y1; mode=line [Attempt B]."),
                             list(method = "restyle",
                                  args = list("y", list(myData$Y2), "mode", "markers"),
                                  label = "1 - Modify 2 attributes via restyle: y=Y2; mode=markers [Attempt B]")
                         )
                         ),
                          
                    ## This one does nothing... at least visible...
                    list( type="buttons", y = 0.1,
                         buttons = list(
                             list(method = "restyle",
                                  args = list( list("y","mode") , list(list(myData$Y1), "line")),
                                  label = "0 - Modify 2 attributes via restyle: y=Y1; mode=line [Attempt C]"),
                             list(method = "restyle",
                                  args = list( list("y","mode") , list(list(myData$Y2), "markers")),
                                  label = "1 - Modify 2 attributes via restyle: y=Y2; mode=markers [Attempt C]")
                         )
                         )
                )
                )

htmlwidgets::saveWidget(as_widget(fig), "mwe.html")

Any tips to help me understand the typing of the restyle method arguments or suggestions on how to get more than 1 argument to be interpreted would help :slight_smile:

So, I managed to find my solution. args is a list of list, then each arg is a list (seems obvious now :p).

                    ## This one works.                                                                                                                                                                                                     
                    list( type="buttons", y = 0.3,
                         buttons = list(
                             list(method = "restyle",
                                  args = list( list( y = list(myData$Y1), mode = list("lines"))),
                                  label = "0 - Modify 2 attributes via restyle: y=Y1; mode=line [The solution]"),
                             list(method = "restyle",
                                  args = list( list( y = list(myData$Y2), mode = list("markers"))),
                                  label = "1 - Modify 2 attributes via restyle: y=Y2; mode=markers [The solution]")
                         )
                         ),

Hoping it will save time and patience for others ! :slight_smile:

2 Likes

Hi,

I have tried to follow the way you modified attributes in the args= argument but with no luck. Will you be able to comment on my post at Modifying multiple attributes to update x axis, y axis and legend in a grouped box plot
?

Here you can find the official docs regarding this.