0

I am trying to update the chart with plotly.js with data from a server. My function should plot updated data in the charts every time new data is sent.

I have two different graphs in my chart. Both with the same X value but different values for the Y axis. I can create the expected graphs in the chart with the first values. But when new values are sent, the restyle function did not update the values.

I don't know how to parse the data to the restyle function. Or, do I need to use a different function?

var source = new EventSource("http://old.iolab.sk/evaluation/sse/sse.php");
source.onmessage = function(event) {
    count++;
    
    if(count == 1){  // only on first data from server
        var layout = {title: "Website graph"};
        var trace1 = {
            x: [event.data.match(/\d+/g)[0]],
            y: [(event.data.match(/\d+/g)[2] + "." + event.data.match(/\d+/g)[3])],   // y1 from server
            name: "hehe",
            type: 'scatter'
          };

          var trace2 = {
            x: [event.data.match(/\d+/g)[0]],
            y: [(event.data.match(/\d+/g)[5] + "." + event.data.match(/\d+/g)[6])],   // y2 from server
            name: "hehe",
            type: 'scatter'
          };

        Plotly.newPlot("websiteGraph", [trace1, trace2], layout);
        return;
    }

    if(!isClicked){      // keeps updating the chart with data from the server until the button is clicked
        trace1 = {'x': [[event.data.match(/\d+/g)[0]]], 'y': [[(event.data.match(/\d+/g)[2] + "." + event.data.match(/\d+/g)[3])]]},
        trace2 = {'x': [[event.data.match(/\d+/g)[0]]], 'y': [[(event.data.match(/\d+/g)[5] + "." + event.data.match(/\d+/g)[6])]]};
        Plotly.restyle("websiteGraph", trace1+trace2);
    
    }
    return;
}

This is the data from the server, one ID is for one update:

id: 0
data: {
data: "x": "0", 
data: "y1": "0.05", 
data: "y2": "1.03" 
data: }

id: 1
data: {
data: "x": "1", 
data: "y1": "0.077452406437284", 
data: "y2": "1.0998476951564" 
data: }

id: 2
data: {
data: "x": "2", 
data: "y1": "0.1048994967025", 
data: "y2": "1.0893908270191" 
data: }

id: 3
data: {
data: "x": "3", 
data: "y1": "0.13233595624294", 
data: "y2": "1.0086295347546" 
data: }

1 Answer 1

0

To answer your question, try using Plotly.react or Plotly.newPlot for new data.

Plotly.restyle seems to be wrong (layout changes only?), as well as some argument passed into the functions.

The comments and examples below are from the Plotly docs at https://plotly.com/javascript/plotlyjs-function-reference/#plotlyrestyle.

To see the code in action, check out this fiddle: https://jsfiddle.net/a0cj6bnm/


In restyle, arrays are assumed to be used in conjunction with the trace indices provided. Therefore, to apply an array as a value, you need to wrap it in an additional array. For example:

var graphDiv = document.getElementById(graphDiv);

var update = {
  opacity: 0.5,
    marker: {
    size: [40, 60, 80, 100],
    color: ['rgb(93, 164, 214)', 'rgb(255, 144, 14)',  'rgb(44, 160, 101)', 'rgb(255, 65, 54)']
  }
}

Plotly.restyle(graphDiv, update, 0);

Note: To me, it seems that restyle is for layout changes only. Not sure though. Instead of 0, restyle can get an array of values but this had no effect on my tests.


newPlot draws a new plot in an element, overwriting any existing plot. To update an existing plot in a , it is much more efficient to use Plotly.react than overwrite it.

The function seems to expect an array and a layout hash as an argument.

var graphDiv = document.getElementById(graphDiv);

var layout = {
  title: "Website graph",
  xaxis: {
    title: 'Year',
    showgrid: false,
    zeroline: false
  },
  yaxis: {
    title: 'Percent',
    showline: false
  }
};

var trace1 = {
  x: [1],
  y: [1],   // y1 from server
  name: "hehe1",
  type: 'scatter'
};

var trace2 = {
  x: [2],
  y: [2], 
  name: "hehe2",
  type: 'scatter'
};

Plotly.newPlot(graphDiv, [trace1, trace2], layout);

Plotly.react has the same signature as Plotly.newPlot above, and can be used in its place to create a plot, but when called again on the same will update it far more efficiently than Plotly.newPlot, which would destroy and recreate the plot. Plotly.react is as fast as Plotly.restyle/Plotly.relayout documented below.

var graphDiv = document.getElementById(graphDiv);

var trace1 = {
  x: [1,2,3,4,5],
  y: [1,3,5,7],   // y1 from server
  name: "hehe1",
  type: 'scatter'
};

var trace2 = {
  x: [2,3,4,5,7,8],
  y: [2,2,2,2,3,4], 
  name: "hehe2",
  type: 'scatter'
};

Plotly.react(graphDiv, [trace1, trace2], layout);
Sign up to request clarification or add additional context in comments.

2 Comments

Thank you for answer, but i managed to solve the problem with addTraces() function
Cool, happy to hear this news. Out of interest: The docs say "traceIndices, array of integer indices into existing value of data (optional, default behaviour is to apply to all traces)", so I guess you have changed trace1+trace2 to the single indexes of both traces, such as [[trace1_idx1, trace1_idx2], [trace2_idx1, trace2_idx2]], right?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.