Plotly scattermapbox赋值customdata后clickData缺失该字段如何解决
问题根因
- customdata格式错误:Plotly的scattermapbox组件的
customdata参数不接收字典类型输入,要求传入与点位数量等长的二维数组,数组每一个子元素对应单个点位的所有自定义字段值 - 组件ID不匹配:定义的dcc.Graph id为
map-graph,回调触发源却写了map-graph1,无法触发对应点位的点击回调 - 模态框输出组件无ID:ModalBody里的两个Label没有设置对应的
id属性,回调输出找不到对应渲染组件 - 参数配置位置错误:
clickmode属于figure全局layout配置,不是单个trace的属性,写在trace里不会生效 - 回调参数/返回值不匹配:关闭按钮的属性名错误写为
n_clicks1,返回值数量与Output定义数量不对应
修复步骤
- 修正customdata与clickmode配置
将customdata改为二维数组格式,每一行对应一个点位的自定义字段,同时把clickmode移到layout配置中:
result_df = pd.DataFrame({'id': [1,2,3,4], 'name':['a','b','c','d'], 'val': [5,6,7,8], 'lat':[.....], 'long':[....] }) data = [] lat = result_df["lat"] lng = result_df["long"] data.append({ "type": "scattermapbox", "lat": lat, "lon": lng, "mode": "markers", # 按[name, id]顺序传入二维数组,每个点位对应一行 "customdata": result_df[["name", "id"]].values.tolist(), "marker": { "symbol": "circle", "size": 12, "opacity": 0.7, "color": "black" } } ) # 构造返回的figure时,把clickmode放到全局layout里 figure = { "data": data, "layout": { "mapbox": { "style": "carto-positron", # 按需替换为你的mapbox样式 "zoom": 10, "center": {"lat": 34.05, "lon": -118.27} }, "clickmode": "event+select", # clickmode移到此处才生效 "margin": {"t":0, "b":0, "l":0, "r":0} } }
- 给模态框输出组件添加ID
dbc.ModalBody( [ dbc.Label("Name:"), dbc.Label(id="name"), # 新增id对应回调输出 html.Br(), dbc.Label("Id:"), dbc.Label(id="val"), # 新增id对应回调输出 ] ),
- 修正回调配置
@application.callback( [ Output("modal-1","is_open"), Output("name","children"), Output("val","children"), ], [ Input("map-graph","clickData"), # 修正为正确的Graph ID Input("c-button", "n_clicks"), Input("close","n_clicks") # 修正属性名为n_clicks ], [ State("modal-1", "is_open") ], prevent_initial_call=True # 避免初始化空值报错 ) def display_popup(clickData, n_clicks, close, is_open): ctx = dash.callback_context if not ctx.triggered: return (no_update, no_update, no_update) trigger_id = ctx.triggered[0]["prop_id"].split(".")[0] if trigger_id == "map-graph" and clickData: # 按存储顺序取customdata,索引0对应name,索引1对应id custom_data = clickData["points"][0]["customdata"] name = custom_data[0] id_val = custom_data[1] return (not is_open, name, id_val) elif trigger_id in ["c-button", "close"]: return (not is_open, no_update, no_update) return (no_update, no_update, no_update)
内容的提问来源于stack exchange,提问作者kms
相关产品推荐
相关产品推荐

