What is the most performant way to update a graph with new data?

I want to update my bar chart using a slider bar for the values of each bar. However, I want the bars to dynamically change as the slider changes. I have achieved this using oninput. Currently, I have the following, which is quite laggy.

HTML

    <head>
        <!-- Plotly.js -->
        <script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
    </head>
    
    <body>
        <h1> Plotly Test</h1>
        <div id="PlotlyTest" style="width: 480px; height: 400px;"><!-- Plotly chart will be drawn inside this DIV --></div>
    
        <p> Adjust Value 1</p>
        <form oninput="amount.value=rangeInput.value">
            <input type="range" id="rangeInput" name="rangeInput" min="0" max="100" value="get_min() " oninput="adjustValue1(this.value)">
            <output name="amount" for="rangeInput"></output>
        </form>
    
        <script src="functionality.js"></script> 
    </body>

JS

    var data = [{
        x: ['VALUE 1'], // in reality I have more values...
        y: [20],
        type: 'bar'
    }];
    Plotly.newPlot('PlotlyTest', data);
    
    function adjustValue1(value)
    {
        data[0]['y'][0] = value;
        Plotly.redraw('PlotlyTest');
    }

According to this, using Plotly.redraw isn’t the fastest method. But then what is?

  • If you’re overriding the data arrays completely, use Plotly.restyle
  • If you’re extending the exciting data arrays, use Plotly.extendTraces

Example with Plotly.restyle:

    var data = [{
        x: ['VALUE 1'], // in reality I have more values...
        y: [20],
        type: 'bar'
    }];
    Plotly.newPlot('PlotlyTest', data);
    
    function adjustValue1(value)
    {
        Plotly.restyle('PlotlyTest', 'y', [[value]]);
    }
2 Likes

Is there a way (or example of it) how to replace the data in a plotly.restyle way in R?
Hours of googling got me no solution.
Thanks for any help

Will that auto scale y axis?

Y axis scale is a layout property. If the scaling is set to auto, it will rescale the axis on data load. Or you can change the axis explicitly with a Plotly.relayout(graphDiv, range_update)

It’s been a while but however, here is an R example for replacing data using Plotly.restyle:

library(shiny)
library(plotly)

initial_plot <- plot_ly(
  type = 'scatter',
  mode = 'lines',
  line = list(color = '#1166FF',
              width = 3)
)

ui <- fluidPage(
  plotlyOutput("myPlot")
)

server <- function(input, output, session) {
  
  myData <- reactiveValues(x = 1, y = runif(1, min=1, max=10))
  
  output$myPlot <- renderPlotly({
    initial_plot
  })
  
  myPlotProxy <- plotlyProxy("myPlot", session)

  observe({
    invalidateLater(1000)
    myData$x <- isolate(c(myData$x, length(myData$x)+1))
    myData$y <- isolate(c(myData$y, runif(1, min=1, max=10)))
    print(myData$x)
    print(myData$y)
  })
  
  observe({
    plotlyProxyInvoke(myPlotProxy, "restyle", list(x = list(myData$x), y = list(myData$y)))
  })
  
}

shinyApp(ui, server)

2 Likes

Is there a way to do this with Python? I am currently looking for an answer to the same question.

1 Like

Please see help(go.FigureWidget) - Section “Reference”

| Caution: To use plotly_restyle to update a list property (e.g.
| the x property of the scatter trace), the property value
| should be a scalar list containing the list to update with. For
| example, the following command would be used to update the ‘x’
| property of the first trace to the list [1, 2, 3]

import plotly.graph_objects as go
help(go.FigureWidget)
fig = go.Figure(go.Scatter(x=[2, 4, 6]))
print(fig)
fig.plotly_restyle({'x': [[1, 2, 3]]}, 0)
print(fig)
1 Like

hi @ismirsehregal ! I’ve been desperately trying to do something like this, but I’ve been trying to just use plotly itself rather than shiny (I’ve never tried shiny and don’t know anything about it). Do you have a sense of if this would be possible to do within plotly?

If not, the main disadvantage I see of your shiny example here, relative to the base plotly animations, is that the animation seems very jerky, and there seems to be no slider and play/pause to control it. Are those things improveable within shiny? If so, I can maybe invest in trying to learn some shiny, although for now the code is pretty incomprehensible to me.

Thanks a ton for giving my follow-ups a look after all this time. If you can help me with this you would absolutely save me!

@sasin Plotly.restyle is a JS function, of course you can use it directly in JS - here is an example. Furthermore. in R, shiny isn’t required to use Plotly.restyle please see this. The difference to plotly’s animations is, that via Plotly.restyle you can “stream” previously unknown datapoints into your plot. Animations are usually created based on a fixed dataset. All of this can be done in R, Python (via wrapper libraries) or directly in JS.

PS: The above example is “jerky” because it is updated every second: invalidateLater(1000) - just decrease the number if you want faster updates.