Prototyping 3D engineering animation with plotly in Jupyter notebook

I’ve finally had time to return to this problem and I deeply apologize for missing the fact I neglected to post my data source. I’ve been using a random function to generate synthetic data as I scale up from N=30 to N>23000.

#data source
N = 30
vec_x, vec_y, vec_z = [0,0,0]
list_of_lists = []
choice = [-0.2, 0.2]
for i in range(N):
    vec_x = vec_x + np.random.choice(choice)
    vec_y = vec_y + np.random.choice(choice)
    vec_z = vec_z + np.random.choice(choice)
    list_of_lists.append([vec_x, vec_y, vec_z])
points = np.array(list_of_lists)
source = points.T

I’m determine to solve the problem and have reworked the code slightly as I work to find a way through to an answer. Now the list of frames is generated in its own function. But I might try to rework it further so that it returns a dictionary?

#graphics
plt = go.Figure(
    data=[go.Scatter3d(
            x=source[0],
            y=source[1],
            z=source[2],
            name="frame",
            mode="lines",
            line=dict(
                color="darkblue",
                width=2)),
        go.Scatter3d(
            x=source[0],
            y=source[1],
            z=source[2],
            name="curve",
            mode="lines",
            line=dict(
                color="darkblue",
                width=2))],
    layout = 
        go.Layout(
            title = go.layout.Title(text="Title | Total Frames: "+ str(N)),
            scene_aspectmode="cube",
            scene = dict(
                xaxis = dict(range=[-2,2], nticks=10, autorange=False),
                yaxis = dict(range=[-2,2], nticks=10, autorange=False),
                zaxis = dict(range=[-2,2], nticks=10, autorange=False)),
            updatemenus=[dict(type="buttons",
                          buttons=[dict(label="Play",
                                        method="animate",
                                        args=[None])])]),
    frames = animateDataSource(source)
)
plt.show()
def frameMaker(i):
    """
    returns x,y,z dict of currently indexed frame by vector component key
    """
    scale = 10
    list_of_lists = dict({
        "x": [[source[0][i],scale * source[0][i+1]], [source[1][i],source[1][i]], [source[2][i],source[2][i]]],
        "y": [[source[0][i],source[0][i]], [source[1][i],scale * source[1][i+1]], [source[2][i], source[2][i]]],
        "z": [[source[0][i],source[0][i]], [source[1][i],source[1][i]], [source[2][i], scale * source[2][i+1]]]
    })
    return list_of_lists
def animateDataSource(time_series_source):
    """
    Takes lists of x,y,z data and returns a list of plotly frames through the frameMaker function. 
    """
    list_of_frames = []
    for k in range(N-1):
        current_vector_data = frameMaker(k)
        list_of_frames.append(
            go.Frame(
                data=[go.Scatter3d(
                    x = [time_series_source[0][k]],
                    y = [time_series_source[1][k]],
                    z = [time_series_source[2][k]],
                    mode="markers",
                    marker=dict(color="red",size=10,opacity=0.5)),
                go.Scatter3d(
                    x=current_vector_data["x"][0],
                    y=current_vector_data["x"][1],
                    z=current_vector_data["x"][2],
                    line=dict(color='darkblue',width=2)),
                go.Scatter3d(
                    x=current_vector_data["y"][0],
                    y=current_vector_data["y"][1],
                    z=current_vector_data["y"][2],
                    line=dict(color='red',width=2)),
                go.Scatter3d(
                    x=current_vector_data["z"][0],
                    y=current_vector_data["z"][1],
                    z=current_vector_data["z"][2],
                    line=dict(color='red',width=2))],
                layout=go.Layout(
                    title = go.layout.Title(text=str([k+1,list(map(lambda x: round(x,3), time_series_source.T[k]))]))
                )
            )
        )
    return list_of_frames