✊🏿 Black Lives Matter. Please consider donating to Black Girls Code today.
⚡️ Concerned about the grid? Kyle Baranko teaches how to predicting peak loads using XGBoost. Register for the August webinar!

Traces from previous frames in animated scatterplot


I have following data:

hubs batch raw_x raw_ y
0 NaN 8 634006.272684 5.823694e+06
1 4048 8 634006.184948 5.823694e+06
2 3500 8 634006.104805 5.823694e+06
3 2002 8 634006.025005 5.823695e+06
4 3102 8 634005.919790 5.823695e+06
5 3060 8 634005.810445 5.823695e+06
6 1573 8 634005.734756 5.823695e+06
7 NaN 39 634005.536396 5.823695e+06
8 1573 39 634005.501772 5.823695e+06
9 4050 39 634005.427821 5.823695e+06
10 3500 39 634005.412689 5.823696e+06
11 3102 39 634005.347912 5.823696e+06
12 3060 39 634005.217421 5.823697e+06

My goal is to plot for each batch (displayed in frames; one batch per 1 frame) those points and color them with respect to hub column (it means that I want point labaled as 4048 to be for example always blue).

Here is my code which attempts to do that:

fig = px.scatter(data, x=‘raw_x’, y=‘raw_y’, animation_frame=‘batch’,

Unfortunately, in second frame (batch==39) I can see old point from the last frame (which is point labeld as 4048) and I don’t want to see that. How can I do that?

Hi @tryptofanik welcome to the forum! I gave it a try, and the problem disappears if you switch to a continuous color scale, would that work for you? For example

import plotly.express as px
import numpy as np
fig = px.scatter(df, x='raw_x', y='raw_y', animation_frame='batch',
xrange = np.ptp(df['raw_x'])
yrange = np.ptp(df['raw_y'])
fig.update_layout(xaxis_range=(df['raw_x'].min() - 0.05*xrange, df['raw_x'].max() + 0.05*xrange),
                  yaxis_range=(df['raw_y'].min() - 0.05*yrange, df['raw_y'].max() + 0.05*yrange))

When the color column is of str/object type, its values are treated as discrete, hence in your case there will be one trace per point. I think plotly.express assumes that there is the same number of traces in each frame, which might be a bug or a feature… In your example you have 8 points (here traces) for frame=8, and 7 for frame=39, and the last point of frame=8 probably because it’s not replaced in the new frame.

When you switch to a continuous color then you only have one trace per frame so the problem disappears.