title: How to render a plotly plot with preset traces hidden i.e. 'legendonly' based on list
body: <p>Thanks to help on a previous question <a href="https://stackoverflow.com/questions/54822671/r-plotly-how-to-observe-whether-a-trace-is-hidden-or-shown-through-legend-click/54825337?noredirect=1#comment96437291_54825337">here</a> I can now record in a <code>list</code> which <code>traces</code> are hidden in a <code>plotly</code> plot by reading out the legend list of <code>TRUE/legendonly</code> with a piece of <code>javascript</code>, which I use to change the list entries, and the color of associated buttons. </p>
  
  <p>What I'm now also looking to do, is to maintain that <code>TRUE/legendonly</code> status when the plot is re-rendered. In the dummy app below, the <code>plot</code> can be re-rendered with the switch <code>actionbutton</code>, which causes a re-<code>render</code> due to a change of colors. </p>
  
  <p><strong>In other words: how to render the plot with certain traces already having 'legendonly status based on <code>values$tracesPlot1</code> that was altered/recorded the last time the user looked at this particular plot.</strong> </p>
  
  <p>I suspect this would involve some <code>document.getElementById("")</code> approach to get values$tracesPlot1, and then do the opposite of the script that is already in place to get the legend status out of this plot, and send it into the plot, with the use of the same <code>onRender(js, data = "tracesPlot1")</code></p>
  
  <p><strong>HERE:</strong><a href="https://i.stack.imgur.com/YfnJF.gif" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/YfnJF.gif" alt="video"></a>  you can see that when the user goes back to the first color scheme, some of the buttons are still switched off, but the plot of course has all traces visible again, instead of reflecting the button status. </p>
  
  <p><em>p.s.:my app the user can switch the plot between grouped by 1 of 3 columns, causing re-rendering, and I would like to load it back with the same legend elements deselected when it renders</em></p>
  
  <pre><code>library(plotly)
  library(shiny)
  library(htmlwidgets)
  
  js &lt;- c(
    "function(el, x, inputName){",
    "  var id = el.getAttribute('id');",
    "  var d3 = Plotly.d3;",
    "  el.on('plotly_restyle', function(evtData) {",
    "    var out = {};",
    "    d3.select('#' + id + ' g.legend').selectAll('.traces').each(function(){",
    "      var trace = d3.select(this)[0][0].__data__[0].trace;",
    "      out[trace.name] = trace.visible;",
    "    });",
    "    Shiny.setInputValue(inputName, out);",
    "  });",
    "}")
  
  YNElement &lt;-    function(idx){sprintf("YesNo_button-%d", idx)}
  
  ui &lt;- fluidPage(
    fluidRow(
      column(2,
             h5("Keep/Drop choices linked to colorscheme 1"),
             uiOutput('YNbuttons')
  
             ),
      column(8,
    plotlyOutput("plot1")
      ),
    column(2,
           h5('Switch grouping'),
           actionButton(inputId = 'Switch', label = icon('refresh'), style = "color: #f7ad6e;   background-color: white;  border-color: #f7ad6e;
                          height: 40px; width: 40px; border-radius: 6px;  border-width: 2px; text-align: center;  line-height: 50%; padding: 0px; display:block; margin: 2px")
           ), style = "margin-top:150px"
    ),
    verbatimTextOutput("tracesPlot1")
  )
  
  server &lt;- function(input, output, session) {
    values &lt;- reactiveValues(colors = T, NrOfTraces = length(unique(mtcars$cyl)))
  
  
    output$plot1 &lt;- renderPlotly({
      if(values$colors) { colors &lt;- c('red', 'blue', 'green') } else {colors &lt;- c('black', 'orange', 'gray')}
      p1 &lt;- plot_ly()
      p1 &lt;-  add_trace(p1, data = mtcars, x = ~disp, y = ~mpg, type = 'scatter', mode = 'markers', color = ~as.factor(cyl), colors = colors)
      p1 &lt;- layout(p1, title = 'mtcars group by cyl with switching colors')
      p1 %&gt;% onRender(js, data = "tracesPlot1")   
  
    })
  
  
    observeEvent(input$Switch, { values$colors &lt;- !values$colors    })
  
  
    observeEvent(values$NrOfTraces, { 
      values$dYNbs_cyl_el &lt;- rep(T,values$NrOfTraces)
      names(values$dYNbs_cyl_el) &lt;- sapply(1:values$NrOfTraces, function(x) {YNElement(x)})
    })
  
    output$YNbuttons &lt;- renderUI({
      req(values$NrOfTraces)
      lapply(1:values$NrOfTraces, function(el) {
        YNb &lt;- YNElement(el)
         if(values$dYNbs_cyl_el[[YNb]] == T ) {
          div(actionButton(inputId = YNb, label = icon("check"), style = "color: #339FFF;   background-color: white;  border-color: #339FFF;height: 34px; width: 34px; border-radius: 6px;  border-width: 2px; text-align: center;  line-height: 50%; padding: 0px; display:block; margin: 2px"))
        } else {
          div(actionButton(inputId = YNb, label = icon("times"), style = "color: #ff4d4d;   background-color: white;  border-color: #ff4d4d;height: 34px; width: 34px; border-radius: 6px;  border-width: 2px; text-align: center;  line-height: 50%; padding: 0px; display:block; margin: 2px"))
        }
       })
      })  
  
    observeEvent(input$tracesPlot1, {
      listTraces &lt;- input$tracesPlot1
      #values$tracesPlot1 &lt;- input$tracesPlot1
      listTracesTF &lt;- gsub('legendonly', FALSE, listTraces)
      lapply(1:values$NrOfTraces, function(el) {
        if(el &lt;= length(listTracesTF)) {
          YNb &lt;- YNElement(el)
          if(values$dYNbs_cyl_el[[YNb]] != listTracesTF[el]) {
            values$dYNbs_cyl_el[[YNb]] &lt;- listTracesTF[el]
          }
        }
      })
    })
  
    output$tracesPlot1 &lt;- renderPrint({ unlist(input$tracesPlot1)  })
  }
  shinyApp(ui, server)
  </code></pre>