Help building animation from dictionary (building off of Intro to Animations tutorial)

Trying to build off of the example of building an animation from a dictionary here - Intro to Animations | Python | Plotly

Iโ€™m trying to build a simple animation of a dot moving along a sine wave in preparation for developing a more complex animation, but I am having a hard time understanding some of the underlying mechanisms.

In the animation produced by the code below, the figure loads correctly (showing the sine wave defined in base_data_dict)

However, when I click Play, the dot animates correctly, but the background trace of the sine wave disappears. I have tried appending the base_data_dictto the thisFrame dictionary, but it still doesnโ€™t work. I have tried reading the documentation, but I think there is something about the underlying mechanisms of Plotly that I am not understanding.

Any help would be appreciated, thank you!!



import numpy as np

import plotly.graph_objects as go

import dash

import dash_core_components as dcc

import dash_html_components as html

#%%

numFrames = 100

sinX = np.linspace(0,4*np.pi,numFrames)

sinY = np.sin(sinX)

xmin = np.min(sinX)

xmax = np.max(sinX)

ymin = np.min(sinY)

ymax = np.max(sinY)

#%%

# make figure

fig_dict = {

    "data": [],

    "layout": {},

    "frames": []

}

# fill in most of layout

fig_dict["layout"]["xaxis"] = {"range": [xmin*1.1, xmax*1.1], "title": "This is the X axis title"}

fig_dict["layout"]["yaxis"] = {"range": [ymin*1.1, ymax*1.1],"title": "This is the Y axis title"}

fig_dict["layout"]["hovermode"] = "closest"

fig_dict["layout"]["updatemenus"] = [

    {

        "buttons": [

            {

                "args": [None, {"frame": {"duration": 0, "redraw": False},

                                "fromcurrent": True, "transition": {"duration": 0,

                                                                    "easing": "linear"}}],

                "label": "Play",

                "method": "animate"

            },

            {

                "args": [[None], {"frame": {"duration": 0, "redraw": False},

                                  "mode": "immediate",

                                  "transition": {"duration": 0}}],

                "label": "Pause",

                "method": "animate"

            }

        ],

        "direction": "left",

        "pad": {"r": 10, "t": 87},

        "showactive": False,

        "type": "buttons",

        "x": 0.1,

        "xanchor": "right",

        "y": 0,

        "yanchor": "top"

    }

]

sliders_dict = {

    "active": 0,

    "yanchor": "top",

    "xanchor": "left",

    "currentvalue": {

        "font": {"size": 20},

        "prefix": "Frame:",

        "visible": True,

        "xanchor": "right"

    },

    "transition": {"duration": 0, "easing": "linear"},

    "pad": {"b": 10, "t": 50},

    "len": 0.9,

    "x": 0.1,

    "y": 0,

    "steps": []

}

#%% make data

base_data_dict = {

    "x": sinX,

    "y": sinY,

    "mode": "lines+markers",

    "marker": {

           "size": 3

    },

    "name":'sine wave'

}

fig_dict["data"].append(base_data_dict)

#%% make frames

for fr in range(numFrames):

    thisFrame = {"data": [], "name": str(fr)}

    # thisFrame["data"].append(base_data_dict)

    data_dict = {

        "x": np.array(sinX[fr]),

        "y": np.array(sinY[fr]),

        "mode": "markers",

        "text": 'thisFrameDotto',

        "marker": {

            "size": 5,

            "color":"red"

        },

        "name": 'dotto'

    }

    thisFrame["data"].append(data_dict)

    fig_dict["frames"].append(thisFrame)

    slider_step = {"args": [

        [fr],

        {"frame": {"duration": 0, "redraw": False},

         "mode": "immediate",

         "transition": {"duration": 0}}

    ],

        "label": fr,

        "method": "animate"}

    sliders_dict["steps"].append(slider_step)

fig_dict["layout"]["sliders"] = [sliders_dict]

fig = go.Figure(fig_dict)

#%% set up Dash/Plotly 'app server' to display figure

external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']

app = dash.Dash(__name__, external_stylesheets=external_stylesheets)

colors ={

    'background': '#111111',

    'text': '#7FDBFF'

}

#%% send figure data to Dash app server (I guess?!)

app.layout = html.Div(style={'backgroundColor':colors['background']},

    children=[

    html.H1(

        children='Big Title', 

        style={

            'textAlign':'center',

            'color':colors['text']

        }

    ),

    html.Div(

        children='Little Title.',

        style={

            'textAlign': 'center',

            'color': colors['text']

        }

    ),

    dcc.Graph(

        id='example-graph',

        figure=fig

    )

])

# %% actually run the server app

if __name__ == '__main__':

    print('Figure displayed at http://127.0.0.1:8050/')

    app.run_server(debug=True)

For posterity - This answer solved it for me - Underlying plot data dissapears when animation frames are added ยท Issue #2423 ยท plotly/plotly.py ยท GitHub