Only one trace showing per frame in animated plot

I’ve got what is effectively a 3D graph, and want to show the graph building up over time as points that are less than a set distance are joined together (distance is controlled with a slider). The issue is that only the first data trace I add to each frame is showing up. I’ve even tested it by adding either at the start or end of the data list, and it is the first one that shows.

The slider values are the filtration_range values, and the filtration are split up into sublists by when they are inserted based on the filtration_range (so the length of the list are the same). There is a frame for each filtration value, which will show on the slider. Then each frame will add in the new data and keep all previous data.

I’m new to plotly, and have mostly been following the tutorials https://plot.ly/python/animations/ and https://plot.ly/python/3d-network-graph/.

Here is the code.

def wip_plot(point_cloud, filtrations, title, filepath, filtration_range):
    """
    
    :param point_cloud: Numpy array on 3 dimensional points in Euclidean space.
    :param filtrations: List of lists that contains simplices (edge chains), that are grouped based on their value and the filtration range.
    :param title: Title for the plot
    :param filepath: filepath for the plot.
    :param filtration_range: array of various distances to use as ranges when splitting up the simplices being added.
    """
    figure = {
        'data': [],
        'layout': {},
        'frames': []
    }
    figure['layout']['title'] = title
    figure['layout']['scene'] = dict(xaxis=dict(range=[0, 1]),
                                     yaxis=dict(range=[0, 1]),
                                     zaxis=dict(range=[0, 1])
                                     )
    figure['layout']['hovermode'] = 'closest'
    figure['layout']['updatemenus'] = [{
        'buttons': [
            {'args': [None, {'frame': {'duration': 500, 'redraw': True},
                             'fromcurrent': True,  # 'transition': {'duration': 300, 'easing': 'quadratic-in-out'}
                             }],
             'label': 'Play',
             'method': 'animate'}
        ],
        'pad': {'r': 10, 't': 87},
        'showactive': True,
        'type': 'buttons'
    }]
    figure['layout']['sliders'] = {
        'args': [
            'transition', {
                'duration': 400,
            }
        ],
        'initialValue': '0',
        'plotlycommand': 'animate',
        'values': filtration_range,
        'visible': True
    }
    sliders_dict = {
        'active': 0,
        'yanchor': 'top',
        'xanchor': 'left',
        'currentvalue': {
            'font': {'size': 20},
            'prefix': 'Epsilon:',
            'visible': True,
            'xanchor': 'right'
        },
        'pad': {'b': 10, 't': 50},
        'len': 0.9,
        'x': 0.1,
        'y': 0,
        'steps': []
    }
    # make data trace
    xn = point_cloud[:, 0]
    yn = point_cloud[:, 1]
    zn = point_cloud[:, 2]
    colour_iter = cycle(kelly_colors)
    # point trace always displayed.
    point_trace = go.Scatter3d(x=xn,
                               y=yn,
                               z=zn,
                               mode='markers',
                               marker=dict(symbol='circle',
                                           size=1,
                                           color='black'),
                               name="Point cloud")
    figure['data'].append(point_trace)
    # make frames:
    i = 0
    frame_data = [point_trace]
    for filtration in filtrations:
        frame = {'data': None, 'name': str(filtration_range[i])}
        # Only the individual nodes will be added at 0, so no lines are needed.
        if filtration_range[i] > 0:
            xe = []
            ye = []
            ze = []
            insertion_values = []
            for simplex in filtration:
                for v in simplex:
                    xe.append(point_cloud[v][0])
                    ye.append(point_cloud[v][1])
                    ze.append(point_cloud[v][2])
                # add None to break the line.
                xe.append(None)
                ye.append(None)
                ze.append(None)
                insertion_values.append(str(simplex.data))
            edge_trace = go.Scatter3d(x=xe,
                                      y=ye,
                                      z=ze,
                                      mode='lines',
                                      line=dict(color=next(colour_iter)), )
            frame_data.append(edge_trace)
            #frame_data.insert(0, edge_trace)
        # add all data from previous frames.
        frame['data'] = frame_data.copy()
        figure['frames'].append(frame)
        slider_step = {'args': [
            [filtration_range[i]],
            {'frame': {'duration': 300, 'redraw': True},
             'mode': 'immediate',
             'transition': {'duration': 300}}
        ],
            'label': filtration_range[i],
            'method': 'animate'}
        sliders_dict['steps'].append(slider_step)
        i += 1
    figure['layout']['sliders'] = [sliders_dict]
    plotly.offline.plot(figure, filename=filepath + title + ".html")

Thank you for any insight into my issues, and let me know if you need more information about the code.

@eg207

To get a cumulative animation you should add to each frame the previously added edges too.
This is a simple example of such animation: https://plot.ly/~empet/14825/scattermapbox-animation-forum-question/#/
The above notebook was updated to work with plotly 4.0.0.rc1, because I installed it a few days ago.