基于单个DataFrame用Altair/Streamlit生成多模块状态统计图表求助
为每个Module生成独立的Altair柱状图(Streamlit集成)
问题背景
现有如下结构的DataFrame:
testname| owner| seed| duration| status| module| date | t1 | ram | 101 | NA | PASS | M_1 | 03_01_2023_15_42 | t2 | ram | 101 | NA | PASS | M_1 | 03_01_2023_15_42 | t3 | Wong | 101 | NA | PASS | M_2 | 03_01_2023_15_42 | t4 | xin | 101 | NA | FAIL | M_2 | 03_01_2023_15_42 | t11 | ram | 101 | NA | PASS | M_1 | 03_02_2023_15_42 | t22 | ram | 101 | NA | PASS | M_1 | 03_02_2023_15_42 | t33 | Wong | 101 | NA | PASS | M_2 | 03_02_2023_15_42 | t44 | xin | 101 | NA | FAIL | M_2 | 03_02_2023_15_42 |
需求是在Altair+Streamlit环境中,为每个module生成独立图表:X轴为date,Y轴为不同status的计数。
用户尝试的代码均未成功:
基础图表代码:
base_chart = alt.Chart(df).mark_bar().encode( alt.X('date:O'), alt.Y('count(status):O'), color='status' )
多图表拼接尝试:
base_chart.encode(y=alt.Y("column1")) | base_chart.encode(y=alt.Y("column2"))
问题分析
- Y轴类型错误:
count(status)是数值型计数,应该用:Q(定量类型)而非:O(有序类型),否则无法正确渲染柱状图高度。 - 未按
module分组:直接复用基础图表修改编码无法实现按module拆分数据,需要针对性筛选数据或用分面功能。
解决方案
方案1:用Altair分面快速生成子图
这是最简洁的方式,自动按module拆分并生成统一风格的子图:
import altair as alt import pandas as pd import streamlit as st # 初始化DataFrame(替换为你的数据加载逻辑) df = pd.DataFrame([ ["t1", "ram", 101, "NA", "PASS", "M_1", "03_01_2023_15_42"], ["t2", "ram", 101, "NA", "PASS", "M_1", "03_01_2023_15_42"], ["t3", "Wong", 101, "NA", "PASS", "M_2", "03_01_2023_15_42"], ["t4", "xin", 101, "NA", "FAIL", "M_2", "03_01_2023_15_42"], ["t11", "ram", 101, "NA", "PASS", "M_1", "03_02_2023_15_42"], ["t22", "ram", 101, "NA", "PASS", "M_1", "03_02_2023_15_42"], ["t33", "Wong", 101, "NA", "PASS", "M_2", "03_02_2023_15_42"], ["t44", "xin", 101, "NA", "FAIL", "M_2", "03_02_2023_15_42"], ], columns=["testname", "owner", "seed", "duration", "status", "module", "date"]) # 生成分面图表 chart = alt.Chart(df).mark_bar().encode( x=alt.X('date:O', title='日期'), y=alt.Y('count(status):Q', title='状态计数'), color=alt.Color('status:N', title='测试状态') ).facet( row='module:N', # 按module分多行,改用column可分多列 title='各模块测试状态统计' ).resolve_scale( y='independent' # 可选:让每个子图Y轴独立缩放 ) # 在Streamlit中展示 st.altair_chart(chart, use_container_width=True)
方案2:循环生成独立图表并拼接
如果需要为每个图表自定义标题、尺寸等,可循环筛选每个module的数据生成独立图表,再组合展示:
import altair as alt import pandas as pd import streamlit as st # 初始化DataFrame(替换为你的数据加载逻辑) df = pd.DataFrame([...]) # 省略数据初始化代码 # 获取所有唯一的module modules = df['module'].unique() # 存储每个module的图表 charts = [] for mod in modules: # 筛选当前module的数据集 mod_df = df[df['module'] == mod] # 生成独立图表 chart = alt.Chart(mod_df).mark_bar().encode( x=alt.X('date:O', title='日期'), y=alt.Y('count(status):Q', title='状态计数'), color=alt.Color('status:N', title='测试状态') ).properties( title=f'模块 {mod} 测试状态统计', width=400, height=300 ) charts.append(chart) # 横向拼接所有图表(用alt.vconcat或&可纵向拼接) combined_chart = alt.hconcat(*charts) # 在Streamlit中展示 st.altair_chart(combined_chart, use_container_width=True)
内容的提问来源于stack exchange,提问作者Kotesh Malempati
相关产品推荐
相关产品推荐

