如何用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
相关产品推荐
相关产品推荐

