Bokeh 3.4.3 补丁版本解析:图像 Glyph 性能修复、BOKEH_MINIFIED 回滚与 CategoricalSlider 索引修复
2026/9/14 5:16:27 网站建设 项目流程

Bokeh 3.4.3 补丁版本解析:图像 Glyph 性能修复、BOKEH_MINIFIED 回滚与 CategoricalSlider 索引修复

【免费下载链接】bokehInteractive Data Visualization in the browser, from Python项目地址: https://gitcode.com/GitHub_Trending/bo/bokeh

本文基于 Bokeh 官方发布说明 3.4.3.rst 展开,逐条解读该补丁版本修复的 8 个问题,并结合仓库源码(如 settings.py、layouts.py、categorical_slider.ts)剖析每个修复背后的实现原理与对开发者实际使用的影响。读完本文,你将清楚了解 3.4.3 修复了哪些回归、为何这些修复重要,以及如何在自己的项目中验证与规避相关问题。

一、版本概览:一次聚焦回归与文档问题的补丁发布

Bokeh 3.4.3 发布于 2024 年 7 月,属于3.4.x系列中的补丁版本(patch release)。与引入新功能的次版本不同,补丁版本的定位是"稳定优先":在不破坏既有 API 的前提下,修复上一版本引入的小型 bug、回归(regression)以及文档问题。

从官方发布说明看,本次共包含 8 项变更,涵盖以下维度:

变更类型数量涉及模块
性能回归修复1Image类 Glyph
运行时行为修复4HasProps内部、资源加载、网格布局合并、CategoricalSlider索引
类型与打包修复2gridplot()类型提示、*.d.ts文件位置
文档修复1未知 Bokeh 版本告警

下面按发布说明顺序逐一深入解读。

二、修复Image类 Glyph 中继承图像数据的性能回归(#13952)

变更原文:修复了Image类 Glyph 中与继承图像数据(inherited image data)相关的性能回归。

问题背景:Bokeh 的ImageImageRGBAImageURLImage类 Glyph 用于在画布上渲染图像数据。若图像的image属性在模型层级中被继承(例如通过muted或共享数据源等机制复用同一份数据),渲染路径可能出现不必要的重复处理,导致帧率下降或 CPU 占用升高。

修复意义:这是一个典型的"回归"——即新版本重构或新增特性时意外引入了性能劣化。该修复确保图像数据在继承场景下仍能走高效的缓存与绘制路径,对频繁更新图像的实时可视化(如视频流、传感器数据叠加)尤为重要。

说明:本仓库当前版本为4.0.0-dev,若你在旧版本(3.4.2 及更早)中遇到Image类 Glyph 在继承数据场景下的卡顿,升级到 3.4.3 即可获得该修复。

三、修复文档中"未知 Bokeh 版本"的伪告警(#13949)

变更原文:修复了文档中关于未知 bokeh 版本的虚假告警(spurious warning)。

问题背景:Bokeh 文档站点在构建时会检查当前文档对应的版本信息。此前在特定构建路径下,版本检测逻辑可能误判,对已知且合法的版本输出 "unknown bokeh version" 之类的警告,干扰文档维护者的判断,也容易掩盖真实的版本问题。

修复意义:属于文档工程侧的质量修复——减少噪音告警,让真正需要关注的版本不一致问题更容易被发现。对普通使用bokeh servebokeh.io的开发者无直接运行时影响。

四、修复HasProps内部对某些对象的处理(#13970)

变更原文:修复了HasProps内部对某几类对象的处理。

问题背景HasProps是 Bokeh 属性系统的基类,几乎所有 Bokeh 模型(PlotFigure、各种 Widget)都继承自它。它负责属性的声明、校验、序列化与变更通知。本次修复针对的是属性内部机制中对"某些类别的对象"(如特殊容器或非标准 Python 对象)的处理缺陷,此类缺陷可能表现为:属性值在赋值后被意外改写、序列化结果异常,或on_change回调触发的时机/载荷不正确。

修复意义:属性系统是 Bokeh 的"地基",该修复降低了自定义模型(扩展)与复杂数据结构在属性传递链路中的出错概率。

五、恢复BOKEH_MINIFIED=no在资源加载中的支持(#13974)

变更原文:在 resources 中恢复了对BOKEH_MINIFIED=no的支持。

这是本次发布说明中最值得展开的一项,因为它直接关系到开发者如何控制 BokehJS 资源的加载形式。

5.1 环境变量的作用

BOKEH_MINIFIED用于控制 Bokeh 是否加载压缩(minified)版本的 BokehJS 资源。默认情况下该值为True(加载.min.js压缩资源),设置为no时则加载未压缩资源——这在调试 JavaScript 问题时非常关键,因为压缩后的代码几乎无法阅读。

该设置的定义位于 src/bokeh/settings.py 第 753 行附近:

minified = PrioritizedSettingbool

其中dev_default=False意味着在开发模式(BOKEH_DEV=1)下默认即加载未压缩资源。

5.2 设置优先级链

settings.py 的文档字符串详细定义了设置解析的优先级(从高到低):

  1. 函数参数:调用时显式传入的参数优先;
  2. 代码中用户显式设置:如settings.minified = False
  3. 用户指定的配置覆盖文件:如settings.load_config("/path/to/bokeh.yaml")
  4. 环境变量:如BOKEH_MINIFIED=no bokeh serve app.py
  5. 本地用户配置文件${HOME}/.bokeh/bokeh.yaml
  6. 全局系统配置(尚未实现);
  7. 本地默认值:如settings.resources(default="server")
  8. 全局默认值:由设置声明定义的默认值。

5.3 实际用法与验证

以未压缩资源启动 Bokeh 服务器:

BOKEH_MINIFIED=no bokeh serve app.py

也可以通过bokeh命令行查看当前设置:

bokeh settings minified

该命令的实现见 src/bokeh/command/subcommands/settings.py,其中列出了minified对应的环境变量与默认值:

minified BOKEH_MINIFIED True

为什么这是一个"回归修复":在某次重构中,BOKEH_MINIFIED=no这一设置途径可能因资源加载逻辑的改动而失效(环境变量被忽略、总是加载压缩版)。3.4.3 恢复了这条链路,使调试 BokehJS 的开发者重新获得"关闭压缩"的能力。

六、更新package.json*.d.ts文件的位置(#13975)

变更原文:更新了package.json*.d.ts文件的定位。

问题背景:BokehJS 以 npm 包形式发布(包名为@bokeh/bokehjs),其package.json需要声明哪些文件被打包发布、TypeScript 类型入口在哪里。此前*.d.ts的路径声明与实际构建输出目录不一致,导致使用 npm 安装 BokehJS 的 TypeScript 项目无法正确解析类型定义。

当前仓库中的实际配置(bokehjs/package.json):

"files": [ "build/js/bokeh*.min.js", "build/js/lib/**/*.js", "build/js/lib/**/*.d.ts" ], "types": "build/js/lib/bokeh.d.ts",

即:类型声明文件统一输出到build/js/lib/目录,types入口指向build/js/lib/bokeh.d.ts。3.4.3 将files中的.d.ts匹配规则更新为build/js/lib/**/*.d.ts,确保消费者安装包后能拿到完整的类型声明,从而获得 IDE 智能提示与类型检查支持。

七、改进gridplot()的类型提示(#13914)

变更原文:改进了gridplot()的类型提示。

实现细节gridplot()是 Bokeh 布局 API 中用于将多个绘图排列成网格的核心函数,其实现位于 src/bokeh/layouts.py。该函数签名复杂,因为它需要同时支持:

  • 二维列表形式的网格([[p1, p2], [p3, p4]]);
  • 一维列表 +ncols/nrows参数;
  • 带合并单元格的布局(子元素可为None表示跨格)。

3.4.3 为该函数补充了多个重载(overload),见 layouts.py 中的三处def gridplot重载声明。重载使静态类型检查器(如 mypy、pyright)能根据调用参数推断出准确的返回类型,对在类型严格项目中调用gridplot()的开发者是实质性的体验提升:

from bokeh.layouts import gridplot from bokeh.plotting import figure p1 = figure() p2 = figure() gp = gridplot([[p1, p2]], toolbar_location="right") # 类型检查器可正确推断返回 GridPlot

八、修复网格布局中仅涉及单个图时的合并逻辑(#13978)

变更原文:修复了网格布局(grid plot)中仅涉及一个绘图时的合并(merging)问题。

问题背景gridplot()在布局计算阶段会对相邻的绘图进行合并处理(例如共享坐标轴的图合并为一个区域)。当网格中只有一个绘图参与合并时,原有的合并逻辑可能产生异常结果——例如布局尺寸计算错误、绘图被意外缩放或位置偏移。

修复意义:这是典型的边界条件 bug。虽然"只有一个图的网格"看似简单,但在响应式布局(sizing_mode)与工具条合并场景下,单图路径同样需要走完整的合并计算。修复后,gridplot([[p]])这类用法也能得到与多图网格一致的正确布局。

九、修复CategoricalSlider部件的类别索引(#13966)

变更原文:修复了CategoricalSlider部件中类别的索引问题。

9.1 部件定位

CategoricalSlider是 Bokeh 的分类滑块部件:滑块的值不是连续数值,而是来自categories列表的离散类别。其 TypeScript 实现位于 categorical_slider.ts。

9.2 核心转换逻辑与问题根源

该部件的关键代码在_calc_to()_calc_from()中,负责滑块数值与类别字符串之间的双向映射:

// 数值 -> 类别:根据数值向下标取类别 format: { to: (value: number) => categories[Math.round(value)], from: (value: string) => categories.indexOf(value), }, // ... protected _calc_from([value]: number[]): string { return categories[Math.round(value)] }

源码注释明确点出了问题根源:

value may not be an integer due to noUiSlider's FP math

即底层滑块引擎(noUiSlider)基于浮点运算,滑块位置换算出的数值可能是0.99991.0001这类非整数。索引修复前,若直接以浮点数作为数组下标(categories[value]),可能取到undefined或错误的类别,导致滑块显示值与实际值不一致、回调中收到undefined等异常。修复后的实现统一通过Math.round(value)将浮点数收敛到最近整数下标,再访问categories

9.3 对 Python 侧使用者的影响

Python 侧的CategoricalSlider(位于bokeh.models.widgets.sliders)通过categoriesvalue/value_throttled属性与前端交互。3.4.3 之前,拖动滑块快速操作时可能出现"显示类别与value属性不一致"的边界情况;升级后该映射稳定可靠。

十、升级建议与验证方式

  1. 升级路径:3.4.3 为补丁版本,可从任意3.4.x直接升级;3.4.x系列内的 API 保持兼容。
  2. 验证BOKEH_MINIFIED:升级后执行BOKEH_MINIFIED=no bokeh serve app.py,并在浏览器开发者工具中确认加载的是未压缩的 BokehJS 脚本。
  3. 验证CategoricalSlider:构建一个含大量类别的CategoricalSlider,快速拖动滑块并监听value变化,确认始终能取到合法类别字符串。
  4. 验证网格布局:分别运行gridplot([[p]])gridplot([[p1, p2]]),对比两者在sizing_mode="stretch_both"下的尺寸表现。

总结

Bokeh 3.4.3 虽然体量不大(8 项变更),但每项都直指真实痛点:Image类 Glyph 的性能回归影响实时可视化帧率;BOKEH_MINIFIED=no的恢复让 JS 调试链路重新打通;CategoricalSlider的浮点索引问题则关系到分类滑块的数据一致性;gridplot()的类型重载与单图合并修复提升了布局 API 的健壮性。对于生产环境运行在 3.4.x 系列上的项目,这是一个"低风险、高收益"的推荐升级版本。完整的变更清单可查阅仓库中的 3.4.3.rst,后续版本的演进可关注 releases 目录 下的其他发布说明。

【免费下载链接】bokehInteractive Data Visualization in the browser, from Python项目地址: https://gitcode.com/GitHub_Trending/bo/bokeh

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询