- 你没有提供样本数据,所以我模拟了它
- 概念很简单,取两个情节表达图形和框架/轨迹,并使用图形对象整合它们
- 等值线图在 500 毫秒内未重绘,因此动画时间增加
import pandas as pd
import numpy as np
import plotly.express as px
import plotly.graph_objects as go
# build sample data and define required variables
history_df = pd.DataFrame(
{
"x": np.random.uniform(0, 1, 100),
"y": np.random.uniform(0, 1, 100),
"entity_id": np.random.choice(list("abcd"), 100),
}
)
history_df = (
history_df.groupby("entity_id", as_index=False)
.apply(lambda d: d.reset_index(drop=True).assign(step=lambda dd: dd.index // 5))
.reset_index(drop=True)
.assign(step=lambda d: "step " + d["step"].astype(str))
)
hover_data = ["x", "y"]
webgl = None
color_kwargs = {}
# original code
scatter_fig = px.scatter(
history_df,
x="x",
y="y",
animation_frame="step",
animation_group="entity_id",
range_x=(0.0, 1.0),
range_y=(0.0, 1.0),
hover_data=hover_data,
render_mode="webgl" if webgl else "svg",
**color_kwargs
)
contour_fig = px.density_contour(
history_df,
x="x",
y="y",
animation_frame="step",
animation_group="entity_id",
range_x=(0.0, 1.0),
range_y=(0.0, 1.0),
hover_data=None,
)
# build frames to be animated from two source figures. Each frame has 2 traces
frames = [
go.Frame(data=f.data + scatter_fig.frames[i].data, name=f.name)
for i, f in enumerate(contour_fig.frames)
]
# increase duration as contour takes a while to redraw
# increase duration as contour takes a while to redraw
updmenus = [{"args": [None, {"frame": {"duration": 2000}}],"label": "▶","method": "animate",},
{'args': [[None], {'frame': {'duration': 0}, 'mode': 'immediate', 'fromcurrent': True, }],
'label': '◼', 'method': 'animate'} ]
# now can animate...
go.Figure(data=frames[0].data, frames=frames, layout=contour_fig.layout).update_layout(
updatemenus=[{"buttons":updmenus}]
)