深入了解 Python 中的 Bokeh:构建交互式 Web 可视化的强大工具

深入了解 Python 中的 Bokeh:构建交互式 Web 可视化的强大工具

在现代数据科学与商业智能领域,静态图表已无法满足日益增长的交互需求。用户希望不仅能“看”到数据,还能“操作”数据——通过缩放、筛选、悬停提示、联动控件等方式深入探索信息背后的故事。

Bokeh 正是为此而生的一个开源 Python 可视化库。它专为高性能交互式图形展示于现代 Web 浏览器而设计,能够轻松创建动态图表、数据仪表盘和复杂的 Web 数据应用。无论是用于 Jupyter Notebook 中的探索性分析,还是部署为企业级可视化平台,Bokeh 都表现出色。


一、什么是 Bokeh?

Bokeh(读作 /ˈboʊkeɪ/,意为“散焦”)是一个专注于 Web 端交互式可视化的 Python 库,由 Continuum Analytics(现为 Anaconda, Inc.)开发并维护。其最大特点是:用 Python 编写代码,生成可在浏览器中运行的 HTML/JavaScript 图表

核心特性:

特性描述
原生支持交互支持缩放、平移、悬停提示、图例点击隐藏、选择高亮等
基于 Web 技术栈输出为 HTML 文件,可嵌入网页或集成到 Flask/Django 应用
高性能渲染使用 WebGL 加速大规模数据集绘制(如百万点级散点图)
支持流式数据更新适用于实时监控系统(如股票行情、传感器数据)
与 Pandas 深度集成直接使用 DataFrame 作为数据源
可构建复杂仪表盘结合 PanelHoloviews 构建企业级 BI 工具
🎯 适用场景:实时监控面板、地理信息系统(GIS)、金融数据分析、机器学习模型解释界面等。

二、安装与导入

使用 pip 安装 Bokeh:

pip install bokeh 

安装完成后,在 Python 脚本或 Jupyter Notebook 中导入:

from bokeh.plotting import figure, show, output_file, output_notebook from bokeh.models import ColumnDataSource, HoverTool, WheelZoomTool from bokeh.layouts import column, row, gridplot from bokeh.io import curdoc import pandas as pd import numpy as np 

常用模块说明:

模块功能
bokeh.plotting高级绘图接口,最常用
bokeh.models提供底层组件(工具、数据源、小部件等)
bokeh.layouts用于组织多个图表布局
bokeh.io控制输出方式(Notebook / HTML 文件)

三、设置输出环境

Bokeh 支持两种主要输出模式:

1. 在 Jupyter Notebook 中显示

output_notebook() # 启用内联显示(仅需调用一次) 

2. 输出为独立 HTML 文件

output_file("my_plot.html", title="我的第一个 Bokeh 图表") 

⚠️ 注意:必须先调用 output_notebook() 或 output_file() 才能使用 show() 显示图表。

四、基础绘图:使用 figure 和 glyph 方法

Bokeh 使用“画布 + 符号(glyph)”的方式绘图:

  • figure() 创建一个绘图画布;
  • 调用 .line().circle().bar() 等方法添加图形元素(称为 glyphs);
  • 最后用 show() 显示结果。

示例 1:折线图(Line Plot)

x = np.linspace(0, 10, 100) y = np.sin(x) # 创建画布 p = figure(title="正弦函数图像", x_axis_label='x', y_axis_label='sin(x)', width=700, height=400) # 添加折线 p.line(x, y, legend_label="sin(x)", line_width=2, color="blue") # 显示 show(p) 

图表默认包含基本交互工具:拖动平移、滚轮缩放、右键重置等。

示例 2:散点图(Scatter Plot)

N = 100 x = np.random.randn(N) y = np.random.randn(N) colors = ["#%02x%02x%02x" % (int(r), int(g), 150) for r, g in zip(50+2*x, 30+2*y)] sizes = np.abs(y) * 15 p = figure(title="彩色随机散点图", tools="pan,wheel_zoom,box_select,reset") p.circle(x, y, size=sizes, color=colors, alpha=0.6) show(p) 

tools 参数自定义交互工具;alpha 设置透明度;支持框选(box_select)进行数据筛选。

五、使用 ColumnDataSource:更高效的数据管理

ColumnDataSource 是 Bokeh 的核心数据结构,类似于 Pandas DataFrame,但专为前端渲染优化,支持字段映射和动态更新。

df = pd.DataFrame({ 'x': [1, 2, 3, 4, 5], 'y': [6, 7, 2, 4, 5], 'label': ['A', 'B', 'C', 'D', 'E'], 'size': [10, 15, 20, 25, 30] }) source = ColumnDataSource(df) p = figure(title="使用 ColumnDataSource") p.circle('x', 'y', size='size', color='navy', alpha=0.6, source=source) show(p) 

优势:便于后续通过 JavaScript 或 Python 更新数据(如 Dashboards 中使用)。

六、增强交互性:添加 HoverTool(悬停提示)

让用户鼠标悬停时查看详细信息,极大提升用户体验。

hover = HoverTool( tooltips=[ ("Index", "$index"), ("(X,Y)", "(@x, @y)"), ("Label", "@label"), ], mode='point' ) p = figure(tools=[hover, 'pan', 'wheel_zoom'], title="带悬停提示的散点图") p.circle('x', 'y', size='size', source=source, color='red', alpha=0.6) show(p) 

$index@field_name 是 Bokeh 的模板变量:$index:自动索引;@x:引用数据源中的列名。

七、常见图表类型实战

1. 条形图(Bar Chart)

fruits = ['Apples', 'Pears', 'Nectarines', 'Plums', 'Grapes'] counts = [20, 18, 34, 25, 19] p = figure(x_range=fruits, height=350, title="水果销量统计", toolbar_location=None,) p.vbar(x=fruits, top=counts, width=0.9, color="skyblue", legend_label="销量") p.xgrid.grid_line_color = None p.y_range.start = 0 p.legend.orientation = "horizontal" p.legend.location = "top_center" show(p) 

使用 vbar() 绘制垂直条形图,hbar() 可绘制水平条形图。

2. 分组/堆叠条形图

years = ['2021', '2022', '2023'] data = {'fruits': fruits, '2021': [20, 18, 34, 25, 19], '2022': [25, 20, 40, 30, 22], '2023': [30, 25, 45, 35, 28]} source = ColumnDataSource(data=data) p = figure(x_range=fruits, height=400, title="三年水果销量对比") p.vbar_stack(years, x='fruits', width=0.9, color=['#c9d9d3','#718dbf','#e84d60'], source=source, legend_label=years) p.legend.location = "top_left" p.xgrid.grid_line_color = None show(p) 


3. 时间序列图

dates = pd.date_range('2023-01-01', periods=100) values = np.cumsum(np.random.randn(100)) p = figure(title="时间序列走势", x_axis_type="datetime", width=800, height=400) p.line(dates, values, color="green", line_width=2, legend_label="趋势") p.circle(dates[::10], values[::10], size=6, color="red") # 标记关键点 p.legend.location = "top_left" show(p) 

x_axis_type="datetime" 自动处理日期格式。

4. 地理地图(使用 GeoJSON 和 Patches)

Bokeh 支持绘制简单的地理区域图(需准备 GeoJSON 数据):

from bokeh.sampledata.us_states import data as states state_xs = [states[code]["lons"] for code in states] state_ys = [states[code]["lats"] for code in states] p = figure(title="美国各州轮廓", toolbar_location=None) p.patches(state_xs, state_ys, fill_alpha=0.0, line_color="black", line_width=0.8) show(p) 

更复杂的地图推荐结合 geopandas + holoviews 或使用 Plotly。

八、布局管理:组合多个图表

使用 row()column()gridplot() 将多个图表组织在一起。

p1 = figure(width=300, height=300, title="圆形") p1.circle([1, 2, 3], [1, 2, 3]) p2 = figure(width=300, height=300, title="线条") p2.line([1, 2, 3], [3, 2, 1]) p3 = figure(width=300, height=300, title="矩形") p3.vbar([1, 2, 3], 0.5, [1, 2, 3], color="green") layout = gridplot([[p1, p2], [None, p3]], sizing_mode="scale_width") show(layout) 

支持响应式布局(sizing_mode),适配不同屏幕尺寸。

九、构建交互式仪表盘(Apps with Bokeh Server)

Bokeh 不仅能绘图,还能构建动态 Web 应用程序,实现滑块、下拉菜单、按钮等控件联动更新图表。

示例:简单滑块控制频率

from bokeh.layouts import column from bokeh.models import Slider from bokeh.themes import Theme def modify_doc(doc): x = np.linspace(0, 4*np.pi, 200) y = np.sin(x) source = ColumnDataSource(data=dict(x=x, y=y)) plot = figure(height=400, width=600, title="动态正弦波") plot.line('x', 'y', source=source, line_width=3, color="navy", alpha=0.6) def update_freq(attr, old, new): f = slider.value y = np.sin(f * x) source.data = dict(x=x, y=y) slider = Slider(start=0.5, end=5, value=1, step=0.1, title="频率") slider.on_change('value', update_freq) doc.add_root(column(slider, plot)) doc.theme = Theme(json={ 'attrs': { 'Figure': {'background_fill_color': '#f8f8f8'}, 'Title': {'text_font_size': '18px'} } }) # 运行服务:bokeh serve --show your_script.py 

# 运行服务:bokeh serve --show your_script.py

使用命令行启动服务:

访问 http://localhost:5006/app 查看交互应用。

十、保存与导出图表

1. 保存为 HTML 文件

output_file("simple_line.html") show(p) 

2. 导出为 PNG/SVG(需要额外依赖)

npm install -g phantomjs-prebuilt # 或使用 selenium + chrome headless 

然后使用:

from bokeh.io import export_png export_png(p, filename="plot.png") 

注意:图片导出对中文支持有限,建议优先使用 HTML 输出。

十一、Bokeh vs 其他可视化库对比

特性BokehMatplotlibSeabornPlotly
交互性⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐
学习曲线中等简单简单中等
默认美观度良好一般优秀优秀
Web 部署能力强(原生支持)
实时数据支持中等
大数据性能强(WebGL)一般一般中等
适合场景Web 仪表盘、实时监控学术出版、脚本绘图EDA 快速分析交互报告、Dashboards
💡 建议:初学者可从 Seaborn/Plotly 入门;若需构建 Web 级交互应用,Bokeh 是首选之一

十二、最佳实践建议

  1. 优先使用 ColumnDataSource,便于后续动态更新;
  2. 合理配置 tools,避免工具栏过于拥挤;
  3. 使用主题(Theme)统一风格;
  4. 在生产环境中结合 Panelpanel.holoviz.org)快速搭建专业仪表盘。

对大数据使用 webgl=True 提升性能:

p = figure(output_backend="webgl") 

十三、总结

Bokeh 是 Python 生态中最具 Web 思维的可视化库之一。它不仅让你“画出”图表,更能让你“构建”数据产品。其强大的交互能力、灵活的布局系统和对实时数据的支持,使其成为企业级数据可视化项目的理想选择。

通过本文的学习,你应该已经掌握了:

  • 如何安装和配置 Bokeh;
  • 如何绘制常见图表并增强交互性;
  • 如何使用 ColumnDataSource 和 HoverTool
  • 如何组织多图表布局;
  • 如何开发动态 Web 应用(Bokeh Server);
  • Bokeh 在真实项目中的定位与优势。

十四、参考资料

Read more

宜搭-低代码开发师(高级)认证实操题1-待办列表

宜搭-低代码开发师(高级)认证实操题1-待办列表

终于通过了认证!!!耗时整理了一份自己实操的实现步骤,主要是复习使用自定义页面表格实现数据管理页功能✌✌✌希望大家都能顺利通过!!! 1. 考前须知 如下图:需要扫描二维码加入组织,我当时扫描失效,以下是另一种加入组织的方法 步骤1:打开手机钉钉右下角点击我的找到【客服与帮助】 步骤2:在【客服与帮助】页面下滑找到【快捷工具】选择【加入团队】即可根据名称搜索加入组织   2. 项目实操 2.1新增普通表单 2.1.1进行中待办 (1) 创建如下字段: * 待办事项:单行文本组件,必填 * 分类:单选组件,必填,按照个人、工作、其他分类 * 重要度:评分组件,默认值为1,必填 * 设置提醒日期:日期组件,格式为年月日 * 待办详情:多行文本组件 (2)设置重要度的默认值为1

语音识别新篇章:Whisper模型从入门到实战完整指南

语音识别新篇章:Whisper模型从入门到实战完整指南 【免费下载链接】whisper-tiny.en 项目地址: https://ai.gitcode.com/hf_mirrors/openai/whisper-tiny.en 还在为语音识别技术的高门槛而烦恼吗?🤔 今天,让我们一起探索OpenAI Whisper这款革命性的语音识别工具,看看它是如何让语音转文字变得如此简单高效! 🎯 为什么选择Whisper? 想象一下,你正在参加一个重要的国际会议,需要实时记录多国代表的发言内容。传统方法可能需要多名翻译人员协同工作,而Whisper却能一个人搞定所有任务!💪 Whisper的核心优势: * 🚀 一键安装,快速上手 * 🌍 支持98种语言,真正全球化 * 🎵 智能降噪,适应各种环境 * 💰 完全免费开源,商业友好 📦 快速开始:环境搭建全攻略 准备工作 首先,确保你的系统满足以下基本要求: * Python 3.9或更高版本 * 至少8GB内存 * 支持CUDA的GPU(可选,但推荐) 安装步骤 让我们一步步搭建Whisp

智创 AI 新视界 -- AIGC 背后的深度学习魔法:从原理到实践

智创 AI 新视界 -- AIGC 背后的深度学习魔法:从原理到实践

💖💖💖亲爱的朋友们,热烈欢迎你们来到 青云交的博客!能与你们在此邂逅,我满心欢喜,深感无比荣幸。在这个瞬息万变的时代,我们每个人都在苦苦追寻一处能让心灵安然栖息的港湾。而 我的博客,正是这样一个温暖美好的所在。在这里,你们不仅能够收获既富有趣味又极为实用的内容知识,还可以毫无拘束地畅所欲言,尽情分享自己独特的见解。我真诚地期待着你们的到来,愿我们能在这片小小的天地里共同成长,共同进步。💖💖💖 本博客的精华专栏: 1. 大数据新视界专栏系列:聚焦大数据,展技术应用,推动进步拓展新视野。 2. Java 大厂面试专栏系列:提供大厂面试的相关技巧和经验,助力求职。 3. Python 魅力之旅:探索数据与智能的奥秘专栏系列:走进 Python 的精彩天地,感受数据处理与智能应用的独特魅力。 4. Java 性能优化传奇之旅:铸就编程巅峰之路:如一把神奇钥匙,深度开启 JVM 等关键领域之门。丰富案例似璀璨繁星,引领你踏上编程巅峰的壮丽征程。 5. Java 虚拟机(

vscode中远程连接不显示copilot chat图标

前提: 1、有授权的Copilot的github账号(学生认证或购买),vscode已登录账号 2、远程主机已安装Github Copilot和Github Copilot Chat插件 现象: 左侧工具栏没有copilot chat的图标 解决: 打开vscode设置(setting),在设置中搜索"extension kind",点击settings.json 在"remote.extensionKind"中添加: "remote.extensionKind":{"GitHub.copilot":["ui"],"GitHub.copilot-chat":["ui"]} 重启vscode可看见chat图标 参考: 快速解决vscode远程连接时copilot提示脱机状态无法使用的问题