深入了解 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

支持多种格式!JPG/PNG/WebP都能一键抠图

支持多种格式!JPG/PNG/WebP都能一键抠图 你有没有遇到过这样的场景:刚拍完一组产品图,却要花半小时一张张在PS里抠背景;或者临时需要换证件照底色,翻遍教程还是抠不干净发丝边缘;又或者运营同事凌晨发来200张商品图,要求“明天一早就要透明背景版”……别再手动拉蒙版、调容差、擦边缘了——现在,三秒搞定一张高质量抠图,支持JPG、PNG、WebP等主流格式,连截图和网页图片都能直接粘贴处理。 这不是某个付费SaaS工具的宣传语,而是真实可运行的本地AI能力。本文将带你零门槛上手一款由“科哥”二次开发构建的CV-UNet图像抠图镜像——它不依赖网络API、不上传隐私图片、不订阅收费套餐,打开浏览器就能用,且所有操作都在你自己的设备上完成。 更关键的是,它真正做到了“小白友好”:没有命令行、不碰配置文件、不用改代码。上传→点击→下载,全程中文界面,连剪贴板粘贴截图都支持。下面我们就从最常用的单图处理开始,一步步拆解这个高效、稳定、开箱即用的智能抠图方案。 1. 为什么这次抠图体验不一样? 1.1

Polyfill方式解决前端兼容性问题:core-js包结构与各种配置策略

Polyfill方式解决前端兼容性问题:core-js包结构与各种配置策略

简介 在之前我介绍过Babel:解锁Babel核心功能:从转义语法到插件开发,Babel是一个使用AST转义JavaScript语法,提高代码在浏览器兼容性的工具。但有些ECMAScript并不是新的语法,而是一些新对象,新方法等等,这些并不能使用AST抽象语法树来转义。因此Babel利用core-js实现这些代码的兼容性。 core-js是一个知名的前端工具库,里面包含了ECMAScript标准中提供的新对象/新方法等,而且是使用旧版本支持的语法来实现这些新的API。这样即使浏览器没有实现标准中的新API,也能通过注入core-js代码来提供对应的功能。 像这种通过注入代码实现浏览器没有提供的API特性,叫做Polyfill。这个单词的本意是填充材料,在JavaScript领域中,这些注入的代码就类似“填充材料”一样,帮助我们提高代码的兼容性。另外core-js还提供了一些还在提议中的API的实现。 core-js使用方式 使用前后对比 要想看到core-js使用前后的效果对比,首先需要确定某个特性和对应的执行环境,在这个环境中对应的特性不存在。我本地是Node.js

Spring Web MVC从入门到实战

Spring Web MVC从入门到实战

—JavaEE专栏— 1. Spring Web MVC核心概念 1.1 什么是Spring Web MVC Spring Web MVC是基于Servlet API构建的原始Web框架,从一开始就包含在Spring框架中,其正式名称来源于源模块名称(spring-webmvc),通常简称为Spring MVC。 官方定义:Spring Web MVC is the original web framework built on the Servlet API and has been included in the Spring Framework from the very beginning. Servlet是Java Web开发的规范,定义了动态页面开发的技术标准,而Tomcat、Weblogic等Servlet容器则是该规范的具体实现,

双剑破天门:攻防世界Web题解之独孤九剑心法(八)

双剑破天门:攻防世界Web题解之独孤九剑心法(八)

免责声明:用户因使用公众号内容而产生的任何行为和后果,由用户自行承担责任。本公众号不承担因用户误解、不当使用等导致的法律责任 **本文以攻防世界部分题为例进行演示,后续会对攻防世界大部分的web题目进行演示,如果你感兴趣请关注** 目录 一:WEB 2 二:Web_php_unserialize 三:php_rce 四:web_php_include 五:总结 1. WEB 2 2. Web_php_unserialize 3. php_rce 4. web_php_include 一:WEB 2 打开是一个php代码 代码审计 1.首先给了一段密文也就是需要解密的flag 2.然后对传进来的str进行字符串反转($_o) 3.