How to make Scatter3d animation run smoothly?

Hi

here is a reproducible example for Scatter3d animation, where easing property doesn’t seem to be respected.

Q1. Is smoothness of animation supported for Scatter3d as well?
Q2. if supported, how could one get this animation smooth?

Here is the copy-paste of the code from the link above:

import plotly.graph_objects as go
import numpy as np

n_frames = 10
t = np.linspace(0, 10, n_frames)
x, y, z = np.cos(t), np.sin(t), t

frames = [
    go.Frame(
        dict(
            name = f'{k+1}',
            data = [                    
                go.Scatter3d(x=x[k:k+1], y=y[k:k+1], z=z[k:k+1], mode='markers')
            ],
            traces=[0])
        ) for k in range(n_frames)]

updatemenus = [
    dict(
        type='buttons',
        buttons=[dict(label="Play",
                      method="animate",
                      args=[[f'{k+1}' for k in range(n_frames-2)],
                        dict(frame=dict(duration=1000, redraw=True),
                              transition=dict(
                                  duration=100,
                                  easing="linear" # <<=====
                              ),
                              easing="linear", # <<=====
                              fromcurrent=True,
                              mode="immediate")])],
        direction="left",
        pad=dict(r=10, t=85),
        showactive=True, x=0.1, y=0, xanchor="right", yanchor="top")]



fig = go.Figure(
    data=[
        go.Scatter3d(x=x[0:1], y=y[0:1], z=z[0:1], mode='markers')
    ],
    frames=frames
)
fig.update_layout(width=900, height=550,
            scene_xaxis=dict(range=[x.min(), x.max()], autorange=False),
            scene_yaxis=dict(range=[y.min(), y.max()], autorange=False),
            scene_zaxis=dict(range=[z.min(), z.max()], autorange=False)
)
fig.update_layout(
  updatemenus=updatemenus, 
  # sliders=sliders
)

fig.show()

@vak

  1. define more frames
  2. reduce frame duration
  3. set transition duration on 0
  4. remove easing=“linear” (this leads to the default easing method, which is most performant)
import plotly.graph_objects as go
import numpy as np

n_frames = 90
t = np.linspace(0, 4*np.pi, n_frames)
x, y, z = np.cos(t), np.sin(t), t

frames = [
    go.Frame(
        dict(
            name = f'{k+1}',
            data = [                    
                go.Scatter3d(x=x[k:k+1], y=y[k:k+1], z=z[k:k+1], mode='markers')
            ],
            traces=[0])
        ) for k in range(n_frames)]

updatemenus = [
    dict(
        type='buttons',
        buttons=[dict(label="Play",
                      method="animate",
                      args=[[f'{k+1}' for k in range(n_frames-2)],
                        dict(frame=dict(duration=30, redraw=True),
                              transition=dict(
                                  duration=0,
                                  easing="linear" # <<=====
                              ),
                              #easing="linear", # <<=====
                              fromcurrent=True,
                              mode="immediate")])],
        direction="left",
        pad=dict(r=10, t=85),
        showactive=True, x=1.15, y=1, xanchor="right", yanchor="top")]



fig = go.Figure(go.Scatter3d(x=x[0:1], y=y[0:1], z=z[0:1], mode='markers', marker_size=5),
                frames=frames
)
fig.update_layout(width=600, height=600,
            scene_xaxis=dict(range=[x.min(), x.max()], autorange=False),
            scene_yaxis=dict(range=[y.min(), y.max()], autorange=False),
            scene_zaxis=dict(range=[z.min(), z.max()], autorange=False)
)
fig.update_layout(
  updatemenus=updatemenus, 
  # sliders=sliders
)
1 Like

oh, your hints are logical, but they imply that smoothing (easing) isn’t possible, right?

@vak
Removing easing="linear" implies using the default ,easing="cubic", which has the best smoothing effect.
Have you run the modified code I pasted above?

@empet thank you for your answer, yes I ran the code above.

To my understanding, your setup effectively diminishes the absence of smoothing/easing.
In 2D examples the smoothing is clearly and vividly working even with two frames and even with a huge delay between the frames.

@empet do you think it is possible to get a clear smoothing/easing just with two frames for Scatter3d case?

For 3d this is the best possible. It isn’t so performant as 2d. :frowning:

:cry:
do you know the source code location for the successfully working 2D interpolation during the animation and the corresponding code location for 3D that is not yet interpolating?

Or maybe you know who did this great thing in 2D case?

maybe community could help in fixing it if it is clear where to look at and whom to ask about hints

@vak
plotly.py creates the code for animation, more precisely it creates an instance of go.Figure. Then it is serialized as a json dictionary, and passed to plotly.js to run it. I don’t know how plotly.js work. You can address your questions on animation and smoothness on the the plotly.js repo: https://github.com/plotly/plotly.js/issues.

1 Like

https://community.plotly.com/t/animation-in-scatter3d-in-plotly-js/

:disappointed_relieved: