Plotly Dash过滤数据报Key Error 0 悬停触发折线图更新问题求助
调试修复方案
核心报错原因
两类报错来自三个常见问题:
- Dash回调首次触发时,
hoverData默认是None,直接取值hoverData['points'][0]会触发索引错误 - 从
customdata取到的id和df中icustay_id列的数据类型不匹配,比如df里icustay_id是整数格式,取到的id是嵌套列表/字符串格式,就会出现长度不匹配的比较错误 - 筛选后的数据框转置时,如果筛选结果的行索引不是默认的0,直接取
dff_transpose[0]就会触发KeyError 0
修改后的完整代码
import dash import pandas as pd import plotly.express as px @app.callback( dash.dependencies.Output('heart-rate-time-series', 'figure'), [dash.dependencies.Input('crossfilter-indicator-scatter', 'hoverData')]) def update_heart_rate_timeseries(hoverData): # 首次加载兜底:无悬停数据时返回提示图 if hoverData is None: return px.line(title="请悬停在散点上查看患者心率数据") # 修正id取值:确保取到单值,和df的icustay_id类型对齐 id = hoverData['points'][0]['customdata'] # scatter的customdata如果是列表包单值,先取第一个元素 if isinstance(id, (list, tuple)): id = id[0] # 对齐类型:如果df里icustay_id是字符串,把int改成str即可 id = int(id) # 筛选对应id的行,直接用布尔索引即可 dff = df[df['icustay_id'] == id] # 筛选心率列 dff_heart = dff.filter(regex=r'heart_rate') # 转置后重置索引,避免KeyError dff_transpose = dff_heart.T.reset_index(drop=True) dff_transpose.columns = ['heart_rate'] dff_transpose['time'] = range(len(dff_transpose)) # 直接用转置后的df绘图,避免跨df取数长度不匹配 fig = px.line(dff_transpose, x='time', y='heart_rate') fig.update_traces(mode='lines+markers') fig.update_xaxes(showgrid=False) title = 'Patient id: <b>{}</b><br>{}'.format(id, 'Heart rate against time(in hours)') fig.add_annotation(x=0, y=0.89, xanchor='left', yanchor='bottom', xref='paper', yref='paper', showarrow=False, align='left', text=title) fig.update_layout(height=230, margin={'l': 20, 'b': 30, 'r': 10, 't': 10}) return fig
关键修改点说明
- 增加hoverData非空判断,解决首次加载无数据的报错
- 修正id取值逻辑,先判断是否为列表再取单值,同时对齐数据类型,解决长度不匹配的比较错误
- 用
filter方法筛选心率列,写法更简洁 - 转置后重置索引并指定列名,不再依赖默认行索引0,解决KeyError 0问题
- 绘图时直接用转置后的单一数据框取xy参数,避免两个数据框长度不一致的问题
内容的提问来源于stack exchange,提问作者Iwanttobeatuna
相关产品推荐
相关产品推荐

