Reputation: 21
Below is my code that I'm trying to use for animating frames using plotly.graph_objects
. I'm trying to get an animation to work using frames (or traces or whatever, not really sure at this point) and using Scatter3D but it keeps saying that there's an error in Frames.
import plotly.graph_objects as go
import numpy as np
import random
import datetime
#from scipy.spatial import distance
#^used for calculating the distances (euclidean distance).
layout = go.Layout(scene = dict(xaxis = dict(nticks=4, range=[0,150],), yaxis = dict(nticks=4, range=[0,150],), zaxis = dict(nticks=4, range=[0,100],), xaxis_title='X AXIS',
yaxis_title='Y AXIS',
zaxis_title='Z AXIS'),
title="Drone Flight Simulator Example",
updatemenus=[dict(
type="buttons",
buttons=[dict(label="Play",
method="animate",
args=[None])])])
dframes = go.Frame(data=[go.Scatter3d(x=[random.uniform(0, 100)], y=[random.uniform(0, 100)], z=[random.uniform(0, 50)], mode='markers',name = 'drone1',marker=dict(line=dict(color='rgba(8, 109, 210, 1.0)'))),
go.Scatter3d(x=[random.uniform(0, 100)], y=[random.uniform(0, 100)], z=[random.uniform(0, 50)], mode='markers',name = 'drone2',marker=dict(line=dict(color='rgba(210, 34, 34, 1.0)'))),
go.Scatter3d(x=[random.uniform(0, 100)], y=[random.uniform(0, 100)], z=[random.uniform(0, 50)], mode='markers',name = 'drone3',marker=dict(line=dict(color='rgba(18, 119, 68, 1.0)'))),
go.Scatter3d(x=[random.uniform(0, 100)], y=[random.uniform(0, 100)], z=[random.uniform(0, 50)], mode='markers',name = 'drone4',marker=dict(line=dict(color='rgba(10, 10, 183, 1.0)'))),
go.Scatter3d(x=[random.uniform(0, 100)], y=[random.uniform(0, 100)], z=[random.uniform(0, 50)], mode='markers',name = 'drone5',marker=dict(line=dict(color='rgba(255, 127, 0, 1.0)'))),
go.Scatter3d(x=[random.uniform(0, 100)], y=[random.uniform(0, 100)], z=[random.uniform(0, 50)], mode='markers',name = 'drone6',marker=dict(line=dict(color='rgba(255, 0, 255, 1.0)')))])
dframes2 = go.Frame(data=[go.Scatter3d(x=[random.uniform(0, 100)], y=[random.uniform(0, 100)], z=[random.uniform(0, 50)], mode='markers',name = 'drone1',marker=dict(line=dict(color='rgba(8, 109, 210, 1.0)'))),
go.Scatter3d(x=[random.uniform(0, 100)], y=[random.uniform(0, 100)], z=[random.uniform(0, 50)], mode='markers',name = 'drone2',marker=dict(line=dict(color='rgba(210, 34, 34, 1.0)'))),
go.Scatter3d(x=[random.uniform(0, 100)], y=[random.uniform(0, 100)], z=[random.uniform(0, 50)], mode='markers',name = 'drone3',marker=dict(line=dict(color='rgba(18, 119, 68, 1.0)'))),
go.Scatter3d(x=[random.uniform(0, 100)], y=[random.uniform(0, 100)], z=[random.uniform(0, 50)], mode='markers',name = 'drone4',marker=dict(line=dict(color='rgba(10, 10, 183, 1.0)'))),
go.Scatter3d(x=[random.uniform(0, 100)], y=[random.uniform(0, 100)], z=[random.uniform(0, 50)], mode='markers',name = 'drone5',marker=dict(line=dict(color='rgba(255, 127, 0, 1.0)'))),
go.Scatter3d(x=[random.uniform(0, 100)], y=[random.uniform(0, 100)], z=[random.uniform(0, 50)], mode='markers',name = 'drone6',marker=dict(line=dict(color='rgba(255, 0, 255, 1.0)')))])
dframes3 = go.Frame(data=[go.Scatter3d(x=[random.uniform(0, 100)], y=[random.uniform(0, 100)], z=[random.uniform(0, 50)], mode='markers',name = 'drone1',marker=dict(line=dict(color='rgba(8, 109, 210, 1.0)'))),
go.Scatter3d(x=[random.uniform(0, 100)], y=[random.uniform(0, 100)], z=[random.uniform(0, 50)], mode='markers',name = 'drone2',marker=dict(line=dict(color='rgba(210, 34, 34, 1.0)'))),
go.Scatter3d(x=[random.uniform(0, 100)], y=[random.uniform(0, 100)], z=[random.uniform(0, 50)], mode='markers',name = 'drone3',marker=dict(line=dict(color='rgba(18, 119, 68, 1.0)'))),
go.Scatter3d(x=[random.uniform(0, 100)], y=[random.uniform(0, 100)], z=[random.uniform(0, 50)], mode='markers',name = 'drone4',marker=dict(line=dict(color='rgba(10, 10, 183, 1.0)'))),
go.Scatter3d(x=[random.uniform(0, 100)], y=[random.uniform(0, 100)], z=[random.uniform(0, 50)], mode='markers',name = 'drone5',marker=dict(line=dict(color='rgba(255, 127, 0, 1.0)'))),
go.Scatter3d(x=[random.uniform(0, 100)], y=[random.uniform(0, 100)], z=[random.uniform(0, 50)], mode='markers',name = 'drone6',marker=dict(line=dict(color='rgba(255, 0, 255, 1.0)')))])
fig = go.Figure(
data=[dframes],
layout = layout,
frames = [dframes2, dframes3]
)
fig.show()
This is the error I get when I run it.
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-6-f5ffdbc7af9d> in <module>
51 fig = go.Figure(
52 data=[dframes],
---> 53 layout = layout,
54 )
55 #x, y, and z are an array that may be specified as a tuple, list, numpy array, or pandas Series
..env\lib\site-packages\plotly\graph_objs\_figure.py in __init__(self, data, layout, frames, skip_invalid, **kwargs)
612 is invalid AND skip_invalid is False
613 """
--> 614 super(Figure, self).__init__(data, layout, frames, skip_invalid, **kwargs)
615
616 def add_area(
..env\lib\site-packages\plotly\basedatatypes.py in __init__(self, data, layout_plotly, frames, skip_invalid, **kwargs)
155
156 # ### Import traces ###
--> 157 data = self._data_validator.validate_coerce(data, skip_invalid=skip_invalid)
158
159 # ### Save tuple of trace objects ###
..env\lib\site-packages\_plotly_utils\basevalidators.py in validate_coerce(self, v, skip_invalid)
2667
2668 if invalid_els:
-> 2669 self.raise_invalid_elements(invalid_els)
2670
2671 v = to_scalar_or_list(res)
..env\lib\site-packages\_plotly_utils\basevalidators.py in raise_invalid_elements(self, invalid_els)
296 pname=self.parent_name,
297 invalid=invalid_els[:10],
--> 298 valid_clr_desc=self.description(),
299 )
300 )
ValueError:
Invalid element(s) received for the 'data' property of
Invalid elements include: [Frame({
'data': [{'marker': {'line': {'color': 'rgba(8, 109, 210, 1.0)'}},
'mode': 'markers',
'name': 'drone1',
'type': 'scatter3d',
'x': [81.25984067869952],
'y': [48.769639907021364],
'z': [48.487661398426134]},
{'marker': {'line': {'color': 'rgba(210, 34, 34, 1.0)'}},
'mode': 'markers',
'name': 'drone2',
'type': 'scatter3d',
'x': [95.77402762543204],
'y': [66.4392521659158],
'z': [3.668445848937296]},
{'marker': {'line': {'color': 'rgba(18, 119, 68, 1.0)'}},
'mode': 'markers',
'name': 'drone3',
'type': 'scatter3d',
'x': [84.20426374652047],
'y': [73.27668150548764],
'z': [27.740448463558167]},
{'marker': {'line': {'color': 'rgba(10, 10, 183, 1.0)'}},
'mode': 'markers',
'name': 'drone4',
'type': 'scatter3d',
'x': [19.262519390174816],
'y': [18.996893985356188],
'z': [0.42619043687839864]},
{'marker': {'line': {'color': 'rgba(255, 127, 0, 1.0)'}},
'mode': 'markers',
'name': 'drone5',
'type': 'scatter3d',
'x': [90.68411695586907],
'y': [6.141373076308476],
'z': [17.555614211400684]},
{'marker': {'line': {'color': 'rgba(255, 0, 255, 1.0)'}},
'mode': 'markers',
'name': 'drone6',
'type': 'scatter3d',
'x': [89.07884666120684],
'y': [80.58458800193029],
'z': [8.755858833570752]}]
})]
The 'data' property is a tuple of trace instances
that may be specified as:
- A list or tuple of trace instances
(e.g. [Scatter(...), Bar(...)])
- A single trace instance
(e.g. Scatter(...), Bar(...), etc.)
- A list or tuple of dicts of string/value properties where:
- The 'type' property specifies the trace type
One of: ['area', 'bar', 'barpolar', 'box',
'candlestick', 'carpet', 'choropleth',
'choroplethmapbox', 'cone', 'contour',
'contourcarpet', 'densitymapbox', 'funnel',
'funnelarea', 'heatmap', 'heatmapgl',
'histogram', 'histogram2d',
'histogram2dcontour', 'image', 'indicator',
'isosurface', 'mesh3d', 'ohlc', 'parcats',
'parcoords', 'pie', 'pointcloud', 'sankey',
'scatter', 'scatter3d', 'scattercarpet',
'scattergeo', 'scattergl', 'scattermapbox',
'scatterpolar', 'scatterpolargl',
'scatterternary', 'splom', 'streamtube',
'sunburst', 'surface', 'table', 'treemap',
'violin', 'volume', 'waterfall']
- All remaining properties are passed to the constructor of
the specified trace type
(e.g. [{'type': 'scatter', ...}, {'type': 'bar, ...}])
Upvotes: 1
Views: 2184
Reputation: 37299
Probably not relevant anymore but if anyone comes across a similar error: The problem is that you are passing a frame object to the data argument. Simple add dframes["data"]
as follows:
fig = go.Figure(
data=dframes["data"],
layout = layout,
frames = [dframes2, dframes3]
)
In addition, I think it would probably be nicer to just define the list of frames and then take the first one as the initial data one:
frames = [go.Frame(data=[
go.Scatter3d(x=[random.uniform(0, 100)], y=[random.uniform(0, 100)], z=[random.uniform(0, 50)], mode='markers',name = 'drone1',marker=dict(line=dict(color='rgba(8, 109, 210, 1.0)'))),
go.Scatter3d(x=[random.uniform(0, 100)], y=[random.uniform(0, 100)], z=[random.uniform(0, 50)], mode='markers',name = 'drone2',marker=dict(line=dict(color='rgba(210, 34, 34, 1.0)'))),
go.Scatter3d(x=[random.uniform(0, 100)], y=[random.uniform(0, 100)], z=[random.uniform(0, 50)], mode='markers',name = 'drone3',marker=dict(line=dict(color='rgba(18, 119, 68, 1.0)'))),
go.Scatter3d(x=[random.uniform(0, 100)], y=[random.uniform(0, 100)], z=[random.uniform(0, 50)], mode='markers',name = 'drone4',marker=dict(line=dict(color='rgba(10, 10, 183, 1.0)'))),
go.Scatter3d(x=[random.uniform(0, 100)], y=[random.uniform(0, 100)], z=[random.uniform(0, 50)], mode='markers',name = 'drone5',marker=dict(line=dict(color='rgba(255, 127, 0, 1.0)'))),
go.Scatter3d(x=[random.uniform(0, 100)], y=[random.uniform(0, 100)], z=[random.uniform(0, 50)], mode='markers',name = 'drone6',marker=dict(line=dict(color='rgba(255, 0, 255, 1.0)')))])
for _ in range(10)]
go.Figure(data=frames[0]["data"],
frames = frames[1:],
layout = layout).show()
Upvotes: 1