Search code examples
pythonpandasnumpyplotlyslider

How to add sucesive spots in plotly (python) using slider?


I am trying to make a plotly graph which could plot the evolution of a parameter's value along a period of time.

By now, what I've managed to get is plotting individual points. However, I'd like to keep the previos spots plotted while getting an increment on the slider.

My code:

import numpy as np
import plotly.express as px
import pandas as pd

df=pd.read_excel("file.xlsx")
fig=px.scatter(df, x="$R[\Omega]$", y="$X[\Omega]$", title='$U_1/I_1$',animation_frame="t[seg]")
fig["layout"].pop("updatemenus")
fig.show()

Data

df2=pd.DataFrame({"$R[\Omega]$":[-0.092034,-0.096416,-0.103026],
                         "$X[\Omega]$":[0.045707,0.047590,0.039953],
                         "t[seg]":[0.416244,0.417078,0.417912]})

Solution

    • have simulated data as I don't have access to your excel spreadsheet. Named columns consistently with what your code implies
    • need to make sure layout has axes ranges set for all data
    • after building figure, for each frame update the data in traces such that it contains all values from previous frames as well. (Note this assume that t[seg] is numeric)

    full code

    import numpy as np
    import plotly.express as px
    import pandas as pd
    
    # df=pd.read_excel("file.xlsx")
    # generate data in structure implied by question
    df = pd.DataFrame(
        {
            "$R[\Omega]$": np.linspace(0, 100, 250),
            "$X[\Omega]$": np.sin(np.linspace(0, 50, 250)),
            "t[seg]": np.linspace(0, 100, 250) // 10,
        }
    )
    xcol = "$R[\Omega]$"
    ycol = "$X[\Omega]$"
    fcol = "t[seg]"
    fig = px.scatter(
        df, x=xcol, y=ycol, title="$U_1/I_1$", animation_frame=fcol
    )
    fig["layout"].pop("updatemenus")
    # prepare axes to show all values
    fig.update_layout(
        {
            ax: {
                "range": [
                    df[col].min(),
                    df[col].max(),
                ]
            }
            for ax,col in zip(["xaxis", "yaxis"], [xcol,ycol])
        }
    )
    
    # add data into each frame from all preceeding traces
    for fr in fig.frames[1:]:
        df_ = df.loc[df[fcol].le(float(fr.name))]
        for t in fr.data:
            t.update(x=df_[xcol].values, y=df_[ycol].values)
        
    fig
    

    enter image description here