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