Dash调用px.bar绘制柱状图坐标轴识别异常仅识别单变量问题
问题现象
- 基于Dash+Plotly开发带下拉交互的柱状图时,调用
px.bar接口出现坐标轴渲染异常:Y轴默认显示为count计数,无法正确加载预期的年份维度对应数值,程序仅识别单轴变量 - 相同数据逻辑下替换为
px.scatter接口可正常渲染散点图,双轴识别无异常 - 异常复现代码:
from dash import Dash, dcc, html, Input, Output import plotly.express as px import pandas as pd import numpy as np app = Dash(__name__) pf = fr.iloc[2:10,18:25] pf.columns = [prueba1] pf.index = ['CH + CHL','CH','CHL(UST)','CHL','CL + CHL','CL','CHL(UST)','CHL'] app.layout = html.Div(children=[ html.Div([dcc.Dropdown(pf.index,'CH', id='pandas-dropdown-2'), html.Div(id='pandas-output-container')]), dcc.Graph(id='example-graph') ]) Output('example-graph','figure'), Input('pandas-dropdown-2', 'value')) def update_graph(value_input): pff = pf[pf.index == value_input] fig = px.bar(pff, x = np.array(prueba1), y = list(pff.values))#, return fig __name__ == '__main__': app.run_server(debug=True, use_reloader=False)
故障原因
- 核心问题是
px.bar的y轴参数传入格式错误:筛选后得到的pff是单行DataFrame,list(pff.values)得到的是shape为(1, n)的二维嵌套列表,px.bar无法解析该结构的输入,会自动切换到计数统计模式,将Y轴映射为数据条数count,这是标签显示异常的直接原因。px.scatter对不规则输入的容错逻辑不同,会自动展平二维数组,因此看起来可以正常运行。 - 原代码存在基础语法疏漏:缺失回调必须的
@app.callback装饰器、程序入口判断的if关键字,即使参数格式正确也无法正常运行。 - 原代码中Dropdown组件未显式指定
options参数,存在下拉选项加载异常的隐患。
修复方案
按以下步骤调整即可正常渲染柱状图:
- 补全所有语法缺失项,添加回调装饰器、入口判断关键字
- 调整数据传入格式:不要直接给
px.bar传手动转换的嵌套列表,将筛选得到的单行宽表转置为维度-数值格式的长表,直接传入列名作为x、y映射参数,从根源避免维度不匹配问题 - 显式指定Dropdown组件的选项参数,保证交互逻辑正常
修复后的可运行完整代码:
from dash import Dash, dcc, html, Input, Output import plotly.express as px import pandas as pd import numpy as np app = Dash(__name__) # 替换为实际数据源与年份列名即可 prueba1 = ['2017','2018','2019','2020','2021','2022','2023'] pf = fr.iloc[2:10,18:25] pf.columns = prueba1 pf.index = ['CH + CHL','CH','CHL(UST)','CHL','CL + CHL','CL','CHL(UST)','CHL'] app.layout = html.Div(children=[ html.Div([ dcc.Dropdown(options=pf.index, value='CH', id='pandas-dropdown-2'), html.Div(id='pandas-output-container') ]), dcc.Graph(id='example-graph') ]) @app.callback( Output('example-graph','figure'), Input('pandas-dropdown-2', 'value') ) def update_graph(value_input): pff = pf[pf.index == value_input] # 单行宽表转长表,适配px.bar的入参要求 pff_long = pff.T.reset_index() pff_long.columns = ['年份', '指标值'] fig = px.bar(pff_long, x='年份', y='指标值') return fig if __name__ == '__main__': app.run_server(debug=True, use_reloader=False)
注:如果需要保留数组传参的写法,只需将y轴参数修改为
y = pff.values.flatten().tolist()展平为一维数组即可,但是长表传参的写法可读性和鲁棒性更强,更推荐使用。
内容的提问来源于stack exchange,提问作者DVBF
相关产品推荐
相关产品推荐

