Plotly express animation: changes in hoverlabel only applied for the first frame

Viewed 348
import pandas as pd
from pandas import Timestamp
import plotly.express as px

df = pd.DataFrame({'continent': {127: 'South America',
  128: 'South America',
  129: 'South America',
  130: 'South America',
  131: 'South America'},
 'date': {127: Timestamp('2021-03-01 00:00:00'),
  128: Timestamp('2021-03-26 00:00:00'),
  129: Timestamp('2021-04-20 00:00:00'),
  130: Timestamp('2021-05-15 00:00:00'),
  131: Timestamp('2021-06-09 00:00:00')},
 'total_cases': {127: 20465329.0,
  128: 23470911.0,
  129: 26544779.0,
  130: 29891133.0,
  131: 30534015.0}})

fig = px.bar(df, x='continent', y='total_cases', animation_frame=df.date.astype(str),
#              hover_data={'animation_frame':False,
#                         'continent':False,
#                         }
            )

fig.update_traces(hovertemplate='Date:%{animation_frame}<br>Total Cases:%{y}')

Running the above code outputs a barchart with an animation slider. The changes made to the hoverlabel are visible only as long as you dont move the slider. Once you do that and the frame changes, the default plotly.express hoverlabel reappears (I think because the trace updates). Is there any fix to this?

Edit: Adding a GIF to show the issue

enter image description here

1 Answers

This is a known issue, and as of writing the only solution seems to be to add the following to your setup:

for f in fig.frames:
    f.data[0].update(hovertemplate='Date:%{animation_frame}<br>Total Cases:%{y}')

enter image description here

You'll also need to keep:

fig.update_traces(hovertemplate='Date:%{animation_frame}<br>Total Cases:%{y}')

If you don't, then the first frame before you run any animation by pressing play or moving the slider back and forth will still display this:

enter image description here

Complete code:

import pandas as pd
from pandas import Timestamp
import plotly.express as px

df = pd.DataFrame({'continent': {127: 'South America',
  128: 'South America',
  129: 'South America',
  130: 'South America',
  131: 'South America'},
 'date': {127: Timestamp('2021-03-01 00:00:00'),
  128: Timestamp('2021-03-26 00:00:00'),
  129: Timestamp('2021-04-20 00:00:00'),
  130: Timestamp('2021-05-15 00:00:00'),
  131: Timestamp('2021-06-09 00:00:00')},
 'total_cases': {127: 20465329.0,
  128: 23470911.0,
  129: 26544779.0,
  130: 29891133.0,
  131: 30534015.0}})

fig = px.bar(df, x='continent', y='total_cases', animation_frame=df.date.astype(str),
#              hover_data={'animation_frame':False,
#                         'continent':False,
#                         }
            )

fig.update_traces(hovertemplate='Date:%{animation_frame}<br>Total Cases:%{y}')
for f in fig.frames:
    f.data[0].update(hovertemplate='Date:%{animation_frame}<br>Total Cases:%{y}')

fig.show()
Related