Quath Quath - 1 year ago 76
Javascript Question

Using plotly.js animation feature

Yesterday Plotly release the new feature animation!!! So I was very eager to test this out, and with the current lack of documentations (temporary I suppose) I'm struggling quite a bit on how to use it.
I did have a peek into the code on GitHub, but ... not working.

  1. I define my div element in the template:

    <div id="plotDiv"> </div>

  2. I wanted to have the plot responsive to resize events, thus I followed the example on the plotly website:

    const d3 = Plotly.d3;
    const gd3 = d3.select("#plotDiv")
    .style({width: "95%", "margin-left": "2.5%"});
    const gd = gd3.node();

  3. Then generate the data (bits of angular magic and other things) but in the end it looks like this:

    data = {x: [array_ot_dates], y: [array_of_not_so_random_values], type:'bar'};

  4. According to the jsdocs for the animation function, you need to pass a frame:

    let plotlyFrame = {data:data, layout:{}};

  5. Try to call animation!!!

    Plotly.animate(gd, plotlyFrame);

And there it goes Kaboum!

First error is: This element is not a Plotly plot: [object HTMLDivElement]
But when I try this:

Plotly.newPlot(gd, data, {});

I have my plot...

So I tried to "predefine" gd by calling Plotly.plot with empty data and then the animate function...

Plotly.plot(gd, [], {});
// make my data not empty
Plotly.animate(gd, plotlyFrame);

And then I get the following error:

plotly.js:116922 Uncaught (in promise) TypeError: Cannot read property '_module' of undefined(…)

Possibly the second could come from the fact I'm using angular and thus calling the function at one point 3 times in a close row.

Any advices? Ideas?

Answer Source

I'm the person who worked on the animation feature! First of all, you can find the documentation here.

Regarding your specific question, it looks like the answer is that you need to initialize the plot before you animate it (I'll add this to the documentation!). For example:

var frame = [{
  data: {
    y: [...new values...]

Plotly.plot(gd, [{x: [...], y: [...]}]).then(function() {
  Plotly.animate(gd, frame)

If some sort of user input is triggering the animation, the promise probably isn't necessary (since the input event will handle things and is pretty unlikely to get fired before Plotly.plot has had a chance to initialize).

Additionally, at the very least I believe you'll need to actually initialize the plot with the trace you wish to animate. I think you can probably get away with empty data, but you'll still need to at least have a trace defined, e.g. Plotly.plot(gd, [{x: [], y: []}]). I think the issue with your attempted fix is that [] for a list of traces is still empty as far as Plotly is concerned since that tells it nothing about the type of trace that exists. Also FYI, one thing the feature is not really designed to do is to draw the initial plot in a fancy manner. That could likely be accomplished, but it's not automatic given animate on an empty plot.

I hope that's enough to clarify issues! It was a pretty large feature, so we'd love feedback and to hear about successes/failures with it!