如何在Plotly-Dash中通过Graph.extendData扩展trace的text字段?
问题原因
你的代码存在3处配置错误,导致text字段更新不生效、图表渲染异常:
- 初始figure的结构错误:
text是trace的属性,需要写在data数组内部的trace字典里,而不是和data、layout平级。 - 文本数据格式错误:直接用
str(t)会把整个numpy数组转为单条长字符串,没有和每个坐标点一一对应,需要构造逐点对应的文本列表。 - 存储数据序列化错误:numpy数组不能直接存入
dcc.Store,需要转为普通列表,否则前端读取时会出现结构异常。
修正后可运行代码
import dash import dash_html_components as html import dash_core_components as dcc import numpy as np from dash.dependencies import Input, Output, State # Example data (a circle). resolution = 1000 t = np.linspace(0, np.pi * 2, resolution) x, y = np.cos(t), np.sin(t) # 构造逐点对应的文本列表 text = [f"t={v:.2f}" for v in t] # 修正初始figure结构,text放在trace内部 figure = dict( data=[{'x': [], 'y': [], 'text': [], 'mode': 'lines+text'}], # 要显示text需要指定mode包含text layout=dict(xaxis=dict(range=[-1, 1]), yaxis=dict(range=[-1, 1])) ) app = dash.Dash(__name__, update_title=None) # remove "Updating..." from title app.layout = html.Div([ dcc.Graph(id='graph', figure=figure), dcc.Interval(id="interval", interval=25), dcc.Store(id='offset', data=0), # numpy数组转list后存入Store dcc.Store(id='store', data=dict(x=x.tolist(), y=y.tolist(), text=text, resolution=resolution)), ]) app.clientside_callback( """ function (n_intervals, data, offset) { offset = offset % data.x.length; const end = Math.min((offset + 10), data.x.length); // extendData支持text字段更新,格式和x、y保持一致即可 return [[{x: [data.x.slice(offset, end)], y: [data.y.slice(offset, end)], text: [data.text.slice(offset, end)]}, [0], 500], end] } """, [Output('graph', 'extendData'), Output('offset', 'data')], [Input('interval', 'n_intervals')], [State('store', 'data'), State('offset', 'data')] ) if __name__ == '__main__': app.run_server()
替代实现方案
如果需要更灵活的字段更新,也可以放弃extendData,直接在客户端回调中更新整个figure的trace数据:
- 预先在
dcc.Store中存储全量的x、y、text数据 - 回调中根据offset截取需要展示的片段,直接赋值给
figure.data[0].x/y/text属性返回即可,该方式支持所有trace属性的动态更新,不需要遵守extendData的格式约束。
内容的提问来源于stack exchange,提问作者David Ryan
相关产品推荐
相关产品推荐

