Plotly slider not responding

I’m trying to animate a plotly 3D scatter figure and the slider is not responding (see code below). Has anybody got a clue what how to solve the issue?

Thanks and best wishes! Christian

import plotly.graph_objs as go
from plotly.subplots import make_subplots
import numpy as np

# Define the initial plot
x = MC1Array[0,:,0]
y = MC1Array[0,:,1]
z = MC1Array[0,:,2]
fig = go.Figure(data=[go.Scatter3d(x=x, y=y, z=z, mode='markers', marker=dict(size=2))])

# Add frames to the plot
frames = []
for t in range(np.shape(MC1Array[:,:,0])[0]):
    x = MC1Array[t,:,0]
    y = MC1Array[t,:,1]
    z = MC1Array[t,:,2]
    frame = go.Frame(data=[go.Scatter3d(x=x, y=y, z=z, mode='markers', name=f'{t+1}')])
    frames.append(frame)
    

sliders=[dict(steps= [dict(method= 'animate',
                           args= [[ f'{k+1}'],
                                  dict(mode= 'e',
                                  frame= dict( duration=1000, redraw= True ),
                                           transition=dict( duration= 0)
                                          )
                                    ],
                            label=f'{k+1}'
                             ) for k in range(np.shape(MC1Array[:,:,:])[0])],
                transition= dict(duration= 30 ),
                x=0,#slider starting position  
                y=0, 
                currentvalue=dict(font=dict(size=12), 
                                  prefix='Day: ', 
                                  visible=True, 
                                  xanchor= 'center'
                                 ),  
                len=1.0,
                active=1) #slider length)
           ]


# Update the plot with the frames
fig.update(frames=frames)

fig.update_layout(sliders=sliders)

fig.update_scenes(xaxis_visible=False, yaxis_visible=False,zaxis_visible=False )

fig.show()

Try updating dict(mode='e', to : dict(mode= 'immediate',

Thank you for the tip! Unfortunately, it did not work

Keep the immediate revision and also revise this line:

) for k in range(np.shape(MC1Array[:,:,:])[0])],

to:

) for k in range(np.shape(MC1Array)[0])],  

Then see if the slider works.

1 Like

Unfortunately, this did not work as well

Lets try another incremental revision. Keeping prior changes, add this change:

initialize with a name:

fig = go.Figure(data=[go.Scatter3d(x=x, y=y, z=z, mode='markers', marker=dict(size=2), name='0')])

frame creation to start from 1 and adj. array reference:

for t in range(1, np.shape(MC1Array)[0]):

update name:

frame = go.Frame(data=[go.Scatter3d(x=x, y=y, z=z, mode='markers', marker=dict(size=2), name=str(t))], name=str(t))

try string names:

                           args= [[str(k)], 

keeping this:

) for k in range(np.shape(MC1Array)[0])],

(and keeping the immediate revision).

Thanks a lot for this help! Unfortunately, still not solved. The slider worked when I was defining different traces instead of frames. However, the figure was quickly too slow…

Have you tried method update instead of animate?

# Create a scatter3d trace for each timestep
traces = [go.Scatter3d(x=MC1Array[i, :, 0],
                       y=MC1Array[i, :, 1],
                       z=MC1Array[i, :, 2],
                       mode='markers',
                       name=f'Day {i+1}',
                       visible=(i == 0),  # Only the first trace is visible initially
                       marker=dict(size=2))
          for i in range(np.shape(MC1Array)[0])]

fig = go.Figure(data=traces)

# Add slider
slider_steps = [dict(method='update',
                     args=[{'visible': [j == i for j in range(np.shape(MC1Array)[0])]}],
                     label=f'Day {i+1}')
                for i in range(np.shape(MC1Array)[0])]

sliders = [dict(steps=slider_steps,
                transition=dict(duration=30),
                x=0,
                y=0,
                currentvalue=dict(font=dict(size=12),
                                  prefix='Day: ',
                                  visible=True,
                                  xanchor='center'),
                len=1.0,
                active=0)]

fig.update_layout(sliders=sliders)

fig.update_scenes(xaxis_visible=False, yaxis_visible=False, zaxis_visible=False)

fig.show()

This works great for the slider, but the play/pause buttons are not playing anymore :smiley:
Are the buttons possible for the traces as well?

After sliders, try:

play_button = dict(label='Play',
                   method='animate',
                   args=[None, {'fromcurrent': True, 'frame': {'duration': 1000, 'redraw': True}}])

pause_button = dict(label='Pause',
                    method='animate',
                    args=[[None], {'frame': {'duration': 0, 'redraw': False}, 'mode': 'immediate'}])

updatemenus = [dict(type='buttons',
                    showactive=False,
                    buttons=[play_button, pause_button],
                    direction="right",
                    pad={"r": 10, "t": 10},
                    x=0.1,
                    xanchor="left",
                    y=1.1,
                    yanchor="top")]

fig.update_layout(updatemenus=updatemenus, sliders=sliders)

fig.update_scenes(xaxis_visible=False, yaxis_visible=False, zaxis_visible=False)

fig.show()

With this, the buttons show up but do not respond

test this. adds frames each day and animate for slider and buttons

x = MC1Array[0, :, 0]
y = MC1Array[0, :, 1]
z = MC1Array[0, :, 2]
trace = go.Scatter3d(x=x, y=y, z=z, mode='markers', marker=dict(size=2))
fig = go.Figure(data=[trace])

# Add back frames:
frames = [go.Frame(data=[go.Scatter3d(x=MC1Array[i, :, 0],
                                      y=MC1Array[i, :, 1],
                                      z=MC1Array[i, :, 2],
                                      mode='markers',
                                      marker=dict(size=2))],
                   name=f'Day {i+1}')
          for i in range(np.shape(MC1Array)[0])]
fig.frames = frames

#slider
slider_steps = [dict(method='animate',
                     args=[[f'Day {i+1}'], {'frame': {'duration': 0, 'redraw': True}, 'mode': 'immediate'}],
                     label=f'Day {i+1}')
                for i in range(np.shape(MC1Array)[0])]
sliders = [dict(steps=slider_steps,
                transition=dict(duration=30),
                x=0,
                y=0,
                currentvalue=dict(font=dict(size=12),
                                  prefix='Day: ',
                                  visible=True,
                                  xanchor='center'),
                len=1.0,
                active=0)]

#buttons
play_button = dict(label='Play',
                   method='animate',
                   args=[None, {'fromcurrent': True, 'frame': {'duration': 1000, 'redraw': True}}])

pause_button = dict(label='Pause',
                    method='animate',
                    args=[[None], {'frame': {'duration': 0, 'redraw': False}, 'mode': 'immediate'}])

updatemenus = [dict(type='buttons',
                    showactive=False,
                    buttons=[play_button, pause_button],
                    direction="right",
                    pad={"r": 10, "t": 10},
                    x=0.1,
                    xanchor="left",
                    y=1.1,
                    yanchor="top")]

fig.update_layout(updatemenus=updatemenus, sliders=sliders)

fig.update_scenes(xaxis_visible=False, yaxis_visible=False, zaxis_visible=False)

fig.show()
2 Likes

Wow, that did the trick! Thank you so much :slight_smile:

1 Like

Good deal, you bet :+1: