Streamlit ECharts柱状图显示为空,请求技术排查协助
ECharts柱状图显示为空问题排查(数据库取数后无法渲染)
我需要实现一个从数据库读取数据的柱状图,SQL查询已成功获取数据,但ECharts图表显示为空。SQL语句会根据StateType和Incoming_Date动态生成,相关数据和效果如下:
- SQL输出:按
INCOMING_DATE、状态(PASS/FAIL)分组后的计数数据,包含日期、状态、数据量三列 - 期望效果:按日期分组,每个日期下展示PASS和FAIL两个柱状条,对应各自的数据量
- 当前效果:空白的ECharts图表区域,无任何柱状条显示
以下是我使用的代码片段:
StateType = st.selectbox("Status Type: ", ['ORC_TO_PAT_STATUS', 'PAT_TO_PROD_STATUS', 'PROD_TO_ORC_STATUS']) LimitType = st.selectbox("Output Days: ", ['Limit 20', 'Limit 50', 'Limit 100','Limit 200','Limit 300','Limit 500']) if(st.button("Refresh Data")): st.write("Your Status is: ", StateType) sqlquery_string = "SELECT INCOMING_DATE, case when " + StateType + " = 'PASS' then 'PASS' else 'FAIL' end as " + StateType + ", COUNT(INCOMING_DATE) as DataCounts from EDH_PT1_TEST.OMD.EDHTEST_COUNT_RESULTS WHERE (" + StateType + " = 'PASS' OR " + StateType + "= 'FAIL') and result_date = (select max(result_Date) from EDH_PT1_TEST.OMD.EDHTEST_COUNT_RESULTS) GROUP BY INCOMING_DATE , " + StateType + " ORDER BY 1 DESC,2 DESC,3 DESC " + LimitType st.write(sqlquery_string) sql_query = pd.read_sql (sqlquery_string, con) df = pd.DataFrame(sql_query, columns = ['INCOMING_DATE', StateType]) df['INCOMING_DATE'] = df['INCOMING_DATE'].astype(str) newdf=df.set_index(StateType,inplace=False).rename_axis(None) st.table(newdf) st.table(df) st.write(json.dumps(newdf['INCOMING_DATE'].to_list())) st.write(json.dumps(newdf.index.values.tolist())) bar_options = { "xAxis": { "type":'value', "axisTick": {"alignWithLabel": True}, "series":[{"data":json.dumps(newdf['INCOMING_DATE'].to_list()),"type":"bar"}] }, "yAxis": { "type":'value', "data":json.dumps(newdf.index.values.tolist()) } } clicked_label = st_echarts( options=bar_options )
问题根源及修复方案
核心问题点
- ECharts配置结构错误:
series被错误嵌套在xAxis内,不符合ECharts规范,series需与xAxis、yAxis同级 - 轴类型与数据绑定错误:x轴应为类目型(对应日期),y轴为数值型(对应计数),你搞反了轴类型;且数值轴无需手动配置
data - 数据格式错误:用
json.dumps()将列表转为字符串,但ECharts需要原生Python数组,无需JSON序列化 - 数据丢失:处理时丢弃了关键的
DataCounts计数字段,导致图表无数值可渲染
修改后的完整代码(替换按钮触发后的逻辑)
if(st.button("Refresh Data")): st.write("Your Status is: ", StateType) sqlquery_string = "SELECT INCOMING_DATE, case when " + StateType + " = 'PASS' then 'PASS' else 'FAIL' end as " + StateType + ", COUNT(INCOMING_DATE) as DataCounts from EDH_PT1_TEST.OMD.EDHTEST_COUNT_RESULTS WHERE (" + StateType + " = 'PASS' OR " + StateType + "= 'FAIL') and result_date = (select max(result_Date) from EDH_PT1_TEST.OMD.EDHTEST_COUNT_RESULTS) GROUP BY INCOMING_DATE , " + StateType + " ORDER BY 1 DESC,2 DESC,3 DESC " + LimitType st.write(sqlquery_string) sql_query = pd.read_sql(sqlquery_string, con) # 保留所有查询字段,包括关键的DataCounts df = pd.DataFrame(sql_query) df['INCOMING_DATE'] = df['INCOMING_DATE'].astype(str) # 处理数据:对齐每个日期的PASS/FAIL计数,无数据补0 x_data = df['INCOMING_DATE'].unique().tolist() pass_data = df[df[StateType] == 'PASS'].set_index('INCOMING_DATE')['DataCounts'].reindex(x_data).fillna(0).tolist() fail_data = df[df[StateType] == 'FAIL'].set_index('INCOMING_DATE')['DataCounts'].reindex(x_data).fillna(0).tolist() # 正确的ECharts配置 bar_options = { "xAxis": { "type": "category", "data": x_data, "axisTick": {"alignWithLabel": True} }, "yAxis": { "type": "value", "name": "数据量" }, "series": [ { "name": "PASS", "type": "bar", "data": pass_data }, { "name": "FAIL", "type": "bar", "data": fail_data } ], "legend": {"data": ["PASS", "FAIL"]} } clicked_label = st_echarts(options=bar_options)
修改说明
- 保留
DataCounts字段,确保图表有数值可渲染 - 调整ECharts配置结构,将
series放在顶级层级 - 修正轴类型:x轴为类目型绑定日期,y轴为数值型自动适配数据范围
- 直接传递Python列表给ECharts,取消不必要的JSON序列化
- 对齐日期数据,缺失的计数用0填充,避免图表断层
内容的提问来源于stack exchange,提问作者jiju samuel
相关产品推荐
相关产品推荐

