Black Lives Matter. Please consider donating to Black Girls Code today.
https://www.blackgirlscode.com

How to create Time Slider for Plotly Scatter3d (Python)?

I am using plotly in Jupyter Notebook with Python to generate multiple 3D plots. All the data exists as points and thus is plotted with Scatter3d. I am trying to add a time slider to this 3D data like this 2D example here:

My plot looks like this right now:

Each of the traces plotted has a date associated with it, so i can group them by month or whatever time frame. I don’t care about the “animation” but the slider on the bottom would be nice, and i can’t seem to make any progress. My code to plot these circles is below:

Code:

i=0
trace=go.Scatter3d(x=Data['X'][i],y=Data['Y'][i],z=Data['Z'][i])
layout=go.Layout(margin={'l': 0, 'r': 0, 'b': 0, 't': 0})
plot_figure = go.Figure(data=trace, layout=layout)
i=1
while i < len(Data):
    plot_figure.add_trace(go.Scatter3d(x=Data['X'][i],y=Data['Y'][i],z=Data['Z'][i],
             error_z=dict(type='constant',
                 value=Data['Error Top'][i],
                 valueminus=-Data['Error Bottom'][i],
                 thickness=0),
             surfaceaxis=1,
             surfacecolor=Data['Colors'][i],
             mode='lines',
             line=dict(color=Data['Colors'][i])))
    i=i+1    

Any help would be appreciated! Thanks in advance.

Hi there,
Funny enough I have just been working on a scatterplot with slider.
It is not fitted to your code, but maybe my code will help. Sorry if it is messy.

It is for a network graph, so for every timestep t I want to see 4 traces.
I have 150 traces and I am walking through them with while i < len(fig.data).
As I understand fig.data is like a list of traces, so you can index on it.

Another important part is that the data should be added to fig in a flat list in the order you want, and then you make visible from that list based on the indices what you want to be visible.

So- data = listoftraces+listoftraces+listoftraces. , data being a flat list of all traces you have in the correct order.

Some variables might seem strange now, but I cut out some of the code to make it shorter.


trace_list= []
for t in np.arange(0,30, 1):
    trace_list.extend(list(create_traces(t, node_lists))) #On every timestep t I want to visualize 5 traces. 

data=[]
for idx,item in enumerate(trace_list):  # I believe the key is that the format for data should be as though list1+list2
    data.extend(trace_list[idx])
    
    
fig_network = go.Figure(data=data, layout=go.Layout(
                title= 'Virus spread in a Network',
                titlefont_size=16,
                hovermode='closest',
                margin=dict(b=20,l=5,r=5,t=40),
                scene = dict(
                    xaxis=dict(axis),
                    yaxis=dict(axis),
                    zaxis=dict(axis),
                )))

steps = []
i=0

day = 0
while i < len(fig_network.data):
    step=dict(method = 'update', 
             args=[{"visible": [False] * len(fig_network.data)}, #set all traces on invisible, and only the traces you want visible you put visible. 
            
                  ]
             )


    step['args'][0]['visible'][i] = True # In my case a day is 5 traces, the first of 5 I don't want to see, the other 4 I do want to see. Every trace that is not True in that step is not visible.
    fig_network.data[i]['showlegend']=False #the edge trace
    i+=1
    step['args'][0]['visible'][i] = True
    fig_network.data[i]['showlegend']=True
    i+=1
    step['args'][0]['visible'][i] = True
    fig_network.data[i]['showlegend']=True
    i+=1
    step['args'][0]['visible'][i] = True
    fig_network.data[i]['showlegend']=True 
    i+=1
    step['args'][0]['visible'][i] = True
    fig_network.data[i]['showlegend']=True
    i+=1

    steps.append(step)
    day+=1
     
        
sliders = [dict(active=0, steps=steps)]


fig_network.layout.update(sliders=sliders)

1 Like

Yes this worked perfectly! Thank you!!

What if you wanted a particular trace to always be visible?

Nevermind, I figured it out!