[Python] Plotly Express with Animation Frame: Having Issues with Legend and Displaying Points

Discussão em 'Python' iniciado por Stack, Maio 13, 2025.

  1. Stack

    Stack Membro Participativo

    I am trying to make a movie showing the evolution of an estimator. The idea is to draw the history of the estimator after each update. I want to do this as a movie as some updates come in out of sequence and this has been the easiest way to display this.

    The animation_frame option for scatter or line in ploty.express has worked well but when I try and color points, or use anything that makes a legend, I am running into issues.

    1. The legend only includes items from the first frame. This also leads to any color not on the first frame not drawing.
    2. If I make a "zeroeth" frame with all the data to get the legend correct a color is only updated correctly sometimes. For example when a frame updates a blue point all blue points are correct but red points are not updated, even if they should change.

    Here is a code snippet showing the first problem. It is a simple scatter of some y=x points. Each frame has one new point compared to the last and points above (3, 3) are red. Doing this in what I think is the simplest way leads to red points not being displayed in the legend or on the graph.

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

    # Make a y=x line that grows from origin (0, 0), to (9, 9)
    x = [val for stop in range(10) for val in np.arange(0, stop, 1)]
    frame_id = [stop for stop in range(10) for _ in np.arange(0, stop, 1)]
    y = x
    color = ['blue' if val < 3 else 'red' for val in x]


    simple_df = pd.DataFrame().assign(
    x=x,
    y=y,
    color=color,
    frame_id=frame_id,
    ).sort_values(by='frame_id')

    px.scatter(
    simple_df, x='x', y='y', color='color', animation_frame='frame_id'
    ).update_layout(
    title='Animation of y=x line growing from (0, 0) to (9, 9)',
    ).update_yaxes(range=[-1, 10]).update_xaxes(range=[-1, 10]).show()


    I have sort of fixed this by adding a starting frame with all points displayed. I have made this less ugly in real code by setting the size of the points to zero, but am displaying them here for clarity. The issue now is only colors that are added on a given frame are handled correctly. So on frames 1-3 blue points only are updated. This leads to the red points hanging around until the first frame where a red point is added. This leads to further issues when going forwards and backwards using the slider but I think this movie rolling forward displays the core of the issue.

    zero_frame = pd.concat([simple_df.assign(frame_id=0), simple_df])
    px.scatter(
    zero_frame, x='x', y='y', color='color', animation_frame='frame_id'
    ).update_layout(
    title='Animation of y=x line growing from (0, 0) to (9, 9)',
    ).update_yaxes(range=[-1, 10]).update_xaxes(range=[-1, 10]).show()


    Does anyone have any fixes for this? To re-iterate, in the toy example I would like a line of blue dots to grow from (1, 1) and have dots after (3, 3) be red, with one dot added per frame. I think if this worked I could get it to behave on real data.

    Continue reading...

Compartilhe esta Página