Search code examples
pythonpython-3.xplotlyplotly-dash

How to use slider with plotly in order to show figure from begging to current step?


  • I want to use plotly to show 2 sinuse waves
  • I want to use slider to show the progress from time=0 to current slider step.

I tried to write the following code:

import numpy as np
import pandas as pd

if __name__ == "__main__":

    time    = np.arange(0, 10, 0.1)
    val1    = np.sin(time)
    val2    = np.sin(time) * np.sin(time)

    df          = pd.DataFrame(val1, columns=['val-1'])
    df['val-2'] = val2

    fig = px.scatter(df, animation_frame=df.index)
    fig.update_layout(xaxis_range=[-100, 100])
    fig.update_layout(yaxis_range=[-1.1, 1.1])

    fig.show()

but I can see the current value of the 2 sinuse waves (and not the whole waves from step=0 to current step)

enter image description here

How can I change my code and see the whole sinuse waves from step=0 to current step ?


Solution

  • I don't think it is possible to animate a line chart in Express, so I would have to use a graph object. There is an example in the reference, which I will adapt to your assignment. As for the graph structure, create the initial graph data and the respective frames in the animation, add them to the layout by creating steps and sliders.

    import numpy as np
    import pandas as pd
    import plotly.express as px
    import plotly.graph_objects as go
    
    if __name__ == "__main__":
    
        time    = np.arange(0, 10, 0.1)
        val1    = np.sin(time)
        val2    = np.sin(time) * np.sin(time)
    
        df          = pd.DataFrame(val1, columns=['val-1'])
        df['val-2'] = val2
        
        data = [go.Scatter(mode='lines', x=df.index, y=df['val-1'], name='val-1'),
                go.Scatter(mode='lines', x=df.index, y=df['val-2'], name='val-2')]
        
        steps = []
        for i in df.index:
            step = dict(method="animate", args=[[i], {"title": f'step:{i}'}], label=f'{i}')
            steps.append(step)
    
        sliders = [dict(active=0, currentvalue={"prefix": "Step: "}, steps=steps)]
        
        layout = go.Layout(dict(xaxis=dict(range=[-100,100]),
                                yaxis=dict(range=[-1.1,1.1]),
                                updatemenus=[dict(type='buttons',
                                                  buttons=[dict(label='Start', method='animate', args=[None]),
                                                           dict(label='Pause',
                                                                method='animate',
                                                                args=[[None], dict(frame=dict(
                                                                    duration=0,
                                                                    redraw=False),
                                                                    mode="immediate", 
                                                                    formcurrent=True,
                                                                    transition=dict(duration=0, easing="linear")
                                                                )])],
                                                  direction="left",
                                                  pad=dict(r=10, t=40),
                                                  showactive=False,
                                                  x=0.00,
                                                  xanchor="right",
                                                  y=0,
                                                  yanchor="top")],
                                sliders=sliders
                               ))
            
        frames = []
        for i in df.index:
            frame = go.Frame(data=[go.Scatter(x=df.index[0:i], y=df.loc[0:i,'val-1']),
                                   go.Scatter(x=df.index[0:i], y=df.loc[0:i,'val-2'])],
                       layout=go.Layout(title_text=f'Step:{i}'),
                       name=i)
            frames.append(frame)  
    
    
        fig = go.Figure(data=data, layout=layout, frames=frames)
    
        fig.show()
    

    enter image description here