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

Ubuntu环境下Python的Bokeh HoverTool重复内容去除方案问询

解决Bokeh散点图HoverTool重复元数据提示的方案

针对同一位置大量重复元数据点导致HoverTool提示冗余的问题,最高效的方式是提前对数据进行聚合处理,既减少渲染压力,又能直接展示去重后的元数据及计数。以下是具体实现:

方案一:提前聚合数据(推荐)

利用pandas对原始数据按坐标(x/y)和元数据(meta1/meta2)分组统计,生成包含计数的聚合数据集,再用该数据集绘图。

代码示例

假设你的原始数据存储在pandas DataFrame df 中,包含x、y、meta1、meta2列:

import pandas as pd
from bokeh.plotting import figure, show
from bokeh.models import HoverTool, ColumnDataSource

# 1. 聚合数据:按坐标+元数据分组,统计每组数量
df_agg = df.groupby(['x', 'y', 'meta1', 'meta2']).size().reset_index(name='count')

# 2. 创建聚合后的数据源
source = ColumnDataSource(df_agg)

# 3. 绘制散点图
p = figure()
renderers = p.circle('x', 'y', source=source)

# 4. 配置HoverTool,展示元数据及计数
hover = HoverTool(
    tooltips="""
    <div>
        <span style='font-size: 10px'>metadata1: @meta1</span>
        <span style='font-size: 10px; margin-left: 10px'>metadata2: @meta2</span>
        <span style='font-size: 10px; display: block'>数量: @count</span>
    </div>
    """,
    renderers=[renderers]
)
p.add_tools(hover)

show(p)

这样处理后,同一位置相同元数据的点会被合并成一个,HoverTool直接展示该组的元数据和总数量,完全避免冗余。

方案二:客户端动态聚合(适合无法修改数据源的场景)

如果无法提前处理原始数据,可以通过Bokeh的CustomJS回调在客户端动态聚合Hover提示内容,但这种方式在数据量极大时可能影响性能。

代码示例

from bokeh.models import CustomJS

# 原始数据源(未聚合)
source = ColumnDataSource(df)

# 绘制散点图
p = figure()
renderers = p.circle('x', 'y', source=source)

# 配置HoverTool,使用CustomJS生成提示内容
hover = HoverTool(
    tooltips=None,  # 关闭默认提示,用自定义回调生成
    renderers=[renderers],
    callback=CustomJS(args=dict(source=source), code="""
        // 获取当前 hover 的点索引
        const indices = cb_data.index.indices;
        if (indices.length === 0) return;
        
        // 收集所有相同坐标+元数据的点,统计计数
        const data = source.data;
        const seen = new Map();
        indices.forEach(i => {
            const key = `${data.x[i]}_${data.y[i]}_${data.meta1[i]}_${data.meta2[i]}`;
            seen.set(key, (seen.get(key) || 0) + 1);
        });
        
        // 构建提示内容
        let tooltip = '<div>';
        seen.forEach((count, key) => {
            const [x, y, meta1, meta2] = key.split('_');
            tooltip += `
                <span style='font-size: 10px'>metadata1: ${meta1}</span>
                <span style='font-size: 10px; margin-left: 10px'>metadata2: ${meta2}</span>
                <span style='font-size: 10px; display: block'>数量: ${count}</span>
            `;
        });
        tooltip += '</div>';
        
        // 设置提示框内容
        cb_obj.tooltips = tooltip;
    """)
)
p.add_tools(hover)

show(p)

注意:这种方式仅在Hover触发时临时聚合当前选中区域的点,数据量过大时可能出现延迟,优先推荐方案一。

内容的提问来源于stack exchange,提问作者Loz

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 02:31:08