You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 18:45:58