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

如何用Bokeh制作带Hover Tool的交互式收入分层散点图

用Bokeh实现带Hover Tool的交互式收入分层散点图

嘿,这个需求我熟!用Bokeh完全能轻松实现,而且交互体验比Seaborn好太多。我给你一步步拆解实现过程,保证你看完就能上手:

1. 先导入必备的库

首先得把Bokeh的核心组件和数据处理库备好:

from bokeh.plotting import figure, show, output_notebook  # Jupyter环境用output_notebook,脚本用output_file
from bokeh.models import HoverTool, ColumnDataSource, CategoricalColorMapper
from bokeh.palettes import Category10  # 内置分类色盘,也可以自己定义颜色列表
import pandas as pd

2. 处理数据:给收入分层

不管你用真实数据还是模拟数据,先得给收入划分层级,这样才能用颜色区分。这里我用模拟数据演示,你直接替换成自己的数据集就行:

# 模拟你的数据结构,替换成真实DataFrame
df = pd.DataFrame({
    'x': [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
    'y': [5, 7, 3, 8, 4, 9, 2, 6, 1, 10],
    'income': [30000, 50000, 25000, 70000, 40000, 85000, 20000, 60000, 15000, 90000]
})

# 自定义收入分层规则,你可以根据自己的需求调整阈值
def categorize_income(income):
    if income < 30000:
        return '低收入'
    elif income < 70000:
        return '中等收入'
    else:
        return '高收入'

# 生成收入层级列
df['income_level'] = df['income'].apply(categorize_income)

3. 用ColumnDataSource管理数据

Bokeh的ColumnDataSource是交互功能的核心,把所有需要用到的数据都塞进去,后面关联起来更方便:

source = ColumnDataSource(data=dict(
    x=df['x'],
    y=df['y'],
    income=df['income'],
    income_level=df['income_level']
))

4. 设置颜色映射:区分不同收入层级

这里用分类颜色映射,把每个收入层级对应到不同颜色。如果你的层级是连续的(比如想按收入数值渐变颜色),可以换成LinearColorMapper:

# 定义层级和颜色的对应关系,用内置的Category10色盘取3个颜色
color_mapper = CategoricalColorMapper(
    factors=['低收入', '中等收入', '高收入'],
    palette=Category10[3]
)

5. 创建图表并添加散点

先初始化一个figure,然后添加散点图层,把颜色和收入层级绑定:

p = figure(
    title='交互式收入分层散点图',
    x_axis_label='X轴指标',
    y_axis_label='Y轴指标',
    tools='pan,box_zoom,reset,save'  # 保留常用的交互工具,HoverTool后面单独加
)

# 添加散点,每个点都是独立的,完美支持悬停
scatter = p.scatter(
    x='x',
    y='y',
    source=source,
    color={'field': 'income_level', 'transform': color_mapper},
    size=10,  # 点的大小可以自己调
    alpha=0.8  # 加一点透明度,避免点重叠看不清
)

6. 核心:添加HoverTool悬停交互

这一步就是实现鼠标悬停显示收入的关键,我们可以自定义悬停时显示的内容:

# 只给这个散点图层绑定HoverTool,避免影响其他元素
hover = HoverTool(renderers=[scatter])
# 定义悬停提示框的内容,@后面是数据源里的字段名,{0,0}是格式化数字为千分位格式
hover.tooltips = [
    ('收入', '@income{0,0} 元'),
    ('收入层级', '@income_level'),
    ('X值', '@x'),
    ('Y值', '@y')
]

# 把HoverTool添加到图表里
p.add_tools(hover)

7. 显示或保存图表

如果是在Jupyter Notebook里运行,先调用output_notebook(),然后show(p)就能直接显示;如果是脚本,用output_file()保存成HTML文件:

# Jupyter环境显示
output_notebook()
show(p)

# 或者保存为可交互的HTML文件
# output_file('income_scatter_plot.html')
# show(p)

额外小技巧

  • 如果想让颜色随收入数值渐变(不是分层),把颜色映射换成LinearColorMapper:
    from bokeh.models import LinearColorMapper
    from bokeh.palettes import Viridis256
    
    color_mapper = LinearColorMapper(
        low=df['income'].min(),
        high=df['income'].max(),
        palette=Viridis256
    )
    # 然后scatter的color参数改成 {'field': 'income', 'transform': color_mapper}
    
  • 还可以自定义点的形状,比如marker='square'、'triangle'等,默认是圆形。

这样你就能得到一个完全符合需求的交互式散点图了——每个点都是独立的,鼠标悬停会显示对应收入和层级,不同层级的点颜色也清晰区分,完美替代Seaborn的静态图表!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 03:51:58