在Altair/Streamlit条形图中实现多值Tooltip展示
解决Altair聚合条形图Tooltip显示学生名单的问题
当然可以展示未用于坐标轴的字段作为Tooltip内容,核心问题是直接添加name字段会破坏Altair的聚合逻辑(它会自动按name和得分分组,导致每个学生单独成条),你需要先把同得分的学生名单聚合为一个单一值(比如逗号分隔的字符串),再添加到Tooltip中。
方法一:提前用Pandas聚合数据
先通过Pandas对原始DataFrame做分组聚合,把每个得分对应的学生名字合并成字符串,再用处理后的DataFrame绘图:
import pandas as pd import altair as alt import streamlit as st # 你的原始DataFrame df = pd.DataFrame({ 'name': ['张三', '李四', '王五', '赵六', '孙七'], 'reached points': [80, 80, 90, 90, 80] }) # 按得分聚合,统计学生数量+合并名单 agg_df = df.groupby('reached points').agg( 学生数量=('name', 'size'), 学生名单=('name', lambda x: ', '.join(x)) ).reset_index() # 绘制聚合条形图 chart = alt.Chart(agg_df).mark_bar().encode( x=alt.X('reached points:Q', title='得分'), y=alt.Y('学生数量:Q', title='学生数量'), tooltip=[ alt.Tooltip('reached points:Q', title='得分'), alt.Tooltip('学生数量:Q', title='学生数量'), alt.Tooltip('学生名单:N', title='学生名单') ] ) st.altair_chart(chart, use_container_width=True)
方法二:用Altair原生聚合(无需提前处理DataFrame)
直接在Altair中通过transform_aggregate完成聚合逻辑,把同得分的学生名字合并后传入Tooltip:
import pandas as pd import altair as alt import streamlit as st # 你的原始DataFrame df = pd.DataFrame({ 'name': ['张三', '李四', '王五', '赵六', '孙七'], 'reached points': [80, 80, 90, 90, 80] }) chart = alt.Chart(df).mark_bar().encode( x=alt.X('reached points:Q', title='得分'), y=alt.Y('count()', title='学生数量'), tooltip=[ alt.Tooltip('reached points:Q', title='得分'), alt.Tooltip('count()', title='学生数量'), # 用concat聚合合并学生名字 alt.Tooltip('name:N', title='学生名单', aggregate=alt.AggregateOp.concat, separator=', ') ] ).transform_aggregate( # 按得分分组聚合 groupby=['reached points'] ) st.altair_chart(chart, use_container_width=True)
两种方法都能保证条形图保持原有的聚合形态,同时鼠标悬停时显示对应得分的完整学生名单。
内容的提问来源于stack exchange,提问作者JanD
相关产品推荐
相关产品推荐

