✊🏿 Black Lives Matter. Please consider donating to Black Girls Code today.
🐇 Announcing Dash VTK for 3d simulation graphics. Check out the March webinar.

Animate a scatter3D plot?

I am trying to take the animated area fill example and turn it into an animated 3D scatter plot without luck so far Is this possible? I have placed the xyz axes in scene. What happens to the “updatemenus:” material? I have tried putting in inside and outside of scene.

Here is my code to plot a sphere as a bunch of markers. The camera settings are from another 3D coding that works but may not be appropriate for this.

PhilW

var frames = []

var x = [];
var y = [];
var z = [];
var theta;
var stheta;
var phi;

var n = 300;

for (i = 0; i < n; i++) {
theta = 3.1412 * Math.random();
stheta = Math.sin(theta);
phi = 3.142 * Math.random();

// Find x,y,z

x[i] = stheta * Math.cos(phi);
y[i] = stheta * Math.sin(phi);
z[i] = Math.cos(theta)
}

for (i = 0; i < n; i++) { 
	frames[i] = {data: [{x: [], y: [], z: []}]}
	frames[i].data[0].x = x.slice(0, i+1);
	frames[i].data[0].y = y.slice(0, i+1);
	frames[i].data[0].z = z.slice(0, i+1);
}

Plotly.plot(‘myDiv’, [{
x: frames[1].data[0].x,
y: frames[1].data[0].y,
z: frames[1].data[0].z,

type: 'scatter3D',
mode: 'markers',
line: {color: 'green'}

}], {
title: “Animation”,

		autosize: true,
		width: 500,
		height: 450,
		margin: {l: 0, r: 20, b: 30, t: 30},
		lightposition: {x: 20, y: 1000, z:5},
	
		scene: {		
		camera:	
		{eye:{x:1, y:-1.8, z:1},
		center:{x:-0.5, y:0, z:-0.2}},
	
xaxis: {
  range: [-1,1]},
yaxis: {
  range: [-1,1]},
zaxis: {
  range: [-1,1]},
  
updatemenus: [{
  x: 0.1,
  y: 0,
  yanchor: "top",
  xanchor: "right",
  showactive: false,
  direction: "left",
  type: "buttons",
  pad: {"t": 87, "r": 10},
  buttons: [{
    method: "animate",
    args: [null, {
      fromcurrent: true,
      transition: {
        duration: 0,
      },
      frame: {
        duration: 0,
        redraw: false
      }
    }],
    label: "Play"
  }, {
    method: "animate",
    args: [
      [null],
      {
        mode: "immediate",
        transition: {
          duration: 0
        },		  frame: {
          duration: 0,
          redraw: false
        }
      }
    ],
    label: "Pause"
  }]
}]

} // scene
}).then(function() {
Plotly.addFrames(‘myDiv’, frames);
});

The missing ; in the line

z[i] = Math.cos(theta)
}

is really there, i had a cut/paste issue, so that is not the problem!

The updatemenus attributes will be the same if you only want an Play and Pause button. What’s not working for you exactly?

My apologies for not being more specific. The code as shown above produces zip. However, I now see that If I take the updatemenus out of scene then I get something. However, all I get is a 2D plot, not a 3D plot. Also, how do you fire the animation from code rather than use a plotly button?

thanks for your help.

Doh, I feel stupid. I wrote “scatter3D” instead of “scatter3d”. So now I get a 3D plot. However, I would still like to now how to fire animations not using plotly buttons.

just call Plotly.animate(/* id of your graph div */)

Thanks! This seems like an inefficient way to plot lots of points as each frame gets bigger than the last. Does generating a new trace each time and using addTraces work better - I assume that the layout does not get redrawn each time?

That probably depends on the trace/subplot type. You should give it a shot and tells us about it.