)
Bokeh 图表联动完全指南从联动平移、联动刷选到属性联动Linked Panning / Brushing / Crosshair / Properties【免费下载链接】bokehInteractive Data Visualization in the browser, from Python项目地址: https://gitcode.com/GitHub_Trending/bo/bokeh联动Linked behavior是 Bokeh 交互可视化中最实用的能力之一它让多个独立图表共享同一条数据流或同一组状态实现鼠标在一张图上操作、其他图同步响应的联觉体验。本文以官方用户指南 interaction/linking.rst 为主线结合当前仓库中的完整示例与源码实现系统讲解四种联动方式——联动平移linked panning、联动刷选linked brushing、联动十字线linked crosshair与属性联动linked properties。读完本文你将能够基于bokeh.plotting接口用最少的代码为多图仪表盘、数据表格与图表组合加上联动交互。联动的基本思路共享对象而非复制状态Bokeh 的联动本质上是一种对象共享机制多个模型引用同一个对象实例同一个Range、同一个ColumnDataSource、同一组Span当该对象的状态在浏览器端发生变化时所有引用它的模型都会同步更新。这与复制一份相同数值有本质区别——联动是双向、实时、发生在浏览器 JavaScript 运行时的。官方指南中所有联动示例都基于 bokeh.plotting 高层接口完成无需直接操作底层文档结构。下面分别展开四种联动方式。联动平移Linked panning共享 Range 对象联动平移或联动缩放的目标是拖动或缩放任意一张图时其他图以相同的坐标范围同步响应。实现它只需要在所有figure之间共享Range对象。官方指南对应的完整示例位于 examples/interaction/linking/linked_panning.pyfrom bokeh.layouts import gridplot from bokeh.plotting import figure, show x list(range(21)) y0 x y1 [20-xx for xx in x] y2 [abs(xx-10) for xx in x] # create a new plot s1 figure(width250, height250, titleNone) s1.scatter(x, y0, size10, colornavy, alpha0.5) # create a new plot and share both ranges s2 figure(width250, height250, x_ranges1.x_range, y_ranges1.y_range, titleNone) s2.scatter(x, y1, size10, markertriangle, colorfirebrick, alpha0.5) # create a new plot and share only one range s3 figure(width250, height250, x_ranges1.x_range, titleNone) s3.scatter(x, y2, size10, markersquare, colorolive, alpha0.5) p gridplot([[s1, s2, s3]], toolbar_locationNone) show(p)要点解读共享两个轴s2同时传入x_ranges1.x_range与y_ranges1.y_range因此它与s1在 X、Y 两个方向上的平移、缩放完全绑定只共享一个轴s3只传入x_ranges1.x_range因此它与s1仅在水平方向联动垂直方向仍可独立缩放——这在对比不同量级的数据时非常实用示例中s1的x_range是未显式指定时自动创建的DataRange1d根据数据自动计算范围共享它意味着三张图会共用同一套坐标窗口。源码侧佐证Range 模型族从源码结构看Bokeh 的坐标范围由 src/bokeh/models/ranges.py 中的Range基类及其两个核心子类承担Range所有范围的抽象基类ranges.pyRange1d数值型、显式设定起止的范围ranges.pyDataRange1d根据所关联字形数据自动计算范围ranges.py。无论figure使用哪种范围对象只要多个图引用同一实例联动即成立。指南还提示更复杂的**联动散点图矩阵SPLOMscatterplot matrix**示例见用户指南的统计专题章节 stats.rst读者可在此基础上将本文的共享Range思路推广到 N×N 网格。联动刷选Linked brushing共享 ColumnDataSource联动刷选是最常用的联动形式在一张图上用框选BoxSelect、套索LassoSelect等工具选中若干点其他图上对应的数据点自动高亮为选中状态。Bokeh 中实现联动刷选的方式是在多个字形glyph渲染器之间共享同一个ColumnDataSource。指南原文明确说明只要数据源被共享Bokeh 就能理解作用于某个字形的选择必须传递给所有使用同一数据源的其它字形。官方示例见 examples/interaction/linking/linked_brushing.py它用企鹅采样数据bokeh.sampledata.penguins展示两张图对同一份数据的不同视图from bokeh.layouts import gridplot from bokeh.models import ColumnDataSource from bokeh.plotting import figure, show from bokeh.sampledata.penguins import data from bokeh.transform import factor_cmap SPECIES sorted(data.species.unique()) TOOLS box_select,lasso_select,help source ColumnDataSource(data) left figure(width300, height400, titleNone, toolsTOOLS, background_fill_color#fafafa) left.scatter(bill_length_mm, body_mass_g, sourcesource, colorfactor_cmap(species, Category10_3, SPECIES)) right figure(width300, height400, titleNone, toolsTOOLS, background_fill_color#fafafa, y_axis_locationright) right.scatter(bill_depth_mm, body_mass_g, sourcesource, colorfactor_cmap(species, Category10_3, SPECIES)) show(gridplot([[left, right]]))要点解读左右两张图的数据列不同bill_length_mm与bill_depth_mm但底层都指向同一个source实例因此选择状态天然共享工具栏只保留了box_select、lasso_select与help三种工具避免平移缩放干扰刷选语义颜色通过factor_cmap按物种映射使同一物种的点在两张图上颜色一致便于观察联动结果。进阶DataTable 与散点图联动联动刷选并不局限于图与图之间。官方指南特别演示了DataTable表格控件与散点图之间的双向联动完整代码见 examples/interaction/linking/data_table_plot.py。其核心同样只有一行——表格与散点共享同一个ColumnDataSourcesource ColumnDataSource(mpg) data_table DataTable(sourcesource, columnscolumns, editableTrue, width800, index_position-1, index_headerrow index, index_width60) p figure(width800, height300, toolspan,wheel_zoom,xbox_select,reset, active_dragxbox_select) cty p.scatter(xindex, ycty, fill_color#396285, size8, alpha0.5, sourcesource) hwy p.scatter(xindex, yhwy, fill_color#CE603D, size8, alpha0.5, sourcesource)这个例子还展示了两个值得注意的细节表格双向编辑DataTable(..., editableTrue)打开单元格编辑表格中修改数值会反向更新source从而让散点图位置实时变化每一列通过TableColumn配置了各自的编辑器SelectEditor、NumberEditor、IntEditor、StringEditor与格式化器NumberFormatter、StringFormatterHover 联动HoverTool(renderers[cty], ...)将鼠标悬停的字段信息制造商、型号、排量等以 tooltips 形式展示且悬停检查同样通过共享的source在两张散点图间联动。进阶带过滤的联动刷选CDSView官方指南将数据源共享延伸到一个更精细的场景当两个图展示的是同一数据源的不同子集时选择与悬停依然联动。这由CDSView配合过滤器实现详见 data.rst 的 Linked selection with filtered data 一节对应示例 linked_brushing_subsets.py。例如第二个图使用CDSView只包含 y 值大于 250 或小于 100 的点但无论在哪个图上框选选择状态都会通过底层ColumnDataSource反映到另一张图。联动十字线Linked crosshair共享 Span 覆盖层十字线crosshair工具让用户鼠标经过时在图上绘制一条十字参考线方便跨图对齐数据点。Bokeh 支持为CrosshairTool配置共享的Span实例作为覆盖层overlay从而让多个图的十字线同步移动。官方示例见 examples/interaction/linking/linked_crosshair.pyfrom random import random from bokeh.layouts import row from bokeh.models import CrosshairTool, Span from bokeh.plotting import figure, show x [random() * 10 for _ in range(200)] y [random() * 10 for _ in range(200)] width Span(dimensionwidth, line_dashdashed, line_width2) height Span(dimensionheight, line_dashdotted, line_width2) p1 figure(height400, width400, x_range(0, 10), y_range(0, 10), toolshover, toolbar_locationNone) p1.add_tools(CrosshairTool(overlay[width, height])) p1.circle(x, y, radius0.2, alpha0.3, hover_alpha1.0) p2 figure(height400, width250, x_range(0, 10), y_range(0, 10), toolshover, toolbar_locationNone) p2.add_tools(CrosshairTool(overlay[width, height])) p2.circle(x, y, radius0.2, alpha0.3, hover_alpha1.0) show(row(p1, p2))要点解读先创建两个独立的Span实例width横跨整个绘图区域的水平线与height垂直线并通过line_dash、line_width定制线型两张图分别用CrosshairTool(overlay[width, height])添加十字线工具关键是两组工具引用的是同一对 Span 实例——这是十字线联动的全部秘诀鼠标在任意一张图上移动共享的Span会同步定位到对应坐标另一张图的十字线随之移动。源码侧佐证CrosshairTool 的 overlay 语义在 src/bokeh/models/tools.py 中CrosshairTool的overlay属性被定义为Auto | Span | Tuple(Span, Span)默认值为autotools.py。其 docstring 明确说明当overlay为auto时工具会根据dimensions属性自动创建水平/垂直线当显式传入一个或两个Span实例时提供显式的Span实例即可构造联动十字线只要这些实例在不同图的十字线工具之间共享——这与本文的示例代码完全对应该属性目前标注为实验性experimental未来可能支持除Span之外的其它注解类型。另外Span本体定义于 src/bokeh/models/annotations/geometry.py其dimension属性可取width水平方向或height垂直方向用于决定 Span 的走向。十字线工具本身是被动检查工具passive inspector tool在工具栏中可随时开关不影响其它交互。属性联动Linked properties用 js_link 同步任意模型属性前三种联动都围绕共享同一对象展开而属性联动走的是另一条路线通过Model.js_link把两个模型的不同属性绑定在一起使它们始终保持同步。官方指南的示例将一个圆字形的半径与滑块Slider的值联动起来完整代码见 examples/interaction/linking/linked_properties.pyfrom bokeh.layouts import column from bokeh.models import Slider from bokeh.plotting import figure, show plot figure(width400, height400) r plot.circle([1,2,3,4,5], [3,2,5,6,4], radius0.2, alpha0.5) slider Slider(start0.1, end2, step0.01, value0.2) slider.js_link(value, r.glyph, radius) show(column(plot, slider))拖动滑块时slider.value的变化会实时写入圆的radius属性圆随之放大缩小。指南特别强调该联动完全在 JavaScript 中完成因此既适用于独立的静态 Bokeh 文档standalone documents也适用于 Bokeh Server 应用此时数据仍可在 Python 侧同步。源码侧佐证js_link 的底层实现js_link是bokeh.model.Model提供的便捷方法实现在 src/bokeh/model/model.py。它的本质是添加一个CustomJS回调在一个模型的属性变化时更新另一个模型的属性其签名与语义如下def js_link(self, attr, other, other_attr, attr_selectorNone):attr本模型的属性名other目标 Bokeh 模型other_attr目标模型上要同步的属性名attr_selector自 Bokeh 1.1 版本加入当attr是可下标属性如 RangeSlider 的value元组时用于指定取哪个下标进行链接。源码 docstring 给出了与手写CustomJS完全等价的对照model.py# js_link 写法 select.js_link(value, plot, sizing_mode) # 等价的手写 CustomJS 写法 from bokeh.models import CustomJS select.js_on_change(value, CustomJS(argsdict(otherplot), codeother.sizing_mode this.value))以及使用attr_selector的场景——把 RangeSlider 的左端值绑到图表的 x 范围起点range_slider.js_link(value, plot.x_range, start, attr_selector0)源码还会做两类防御性校验attr必须是本模型真实存在的属性other必须是合法的 BokehModel实例否则抛出ValueErrormodel.py。联动方式选型与更多参考四种联动方式的触发机制与适用场景对比如下联动方式核心机制共享/绑定对象典型场景联动平移共享坐标范围RangeRange1d/DataRange1d多图对齐同一数据窗口对比走势联动刷选共享数据与选择状态ColumnDataSource含CDSView过滤子集多视图刷选高亮、表格与图联动联动十字线共享覆盖层CrosshairTool的overlay中的Span实例跨图对齐数据点、辅助对比读数属性联动属性绑定回调Model.js_link底层为CustomJS滑块、下拉等控件驱动图形属性实践建议需要坐标窗口同步优先考虑共享Range需要选择状态同步优先考虑共享ColumnDataSource两者可以叠加使用js_link适合控件值 → 图形属性这类非数据语义的联动若需要更复杂的自定义联动逻辑指南建议参考用户指南中的控件章节 widgets 相关文档 与 JavaScript 回调章节任意 JavaScript 回调的创建见ug_interaction_js_callbacks对应的 js_callbacks.rst想在一个页面内自由组合多张联动图gridplot见 layouts 相关文档是官方示例中最常用的容器示例代码全部采用show()直接展示同样也适用于output_file/ Bokeh Server 等其它展示方式。所有官方联动示例均集中存放于 examples/interaction/linking 目录linked_panning.py、linked_brushing.py、linked_crosshair.py、linked_properties.py、data_table_plot.py可直接在本地运行观察效果再对照本文源码分析理解其联动原理。【免费下载链接】bokehInteractive Data Visualization in the browser, from Python项目地址: https://gitcode.com/GitHub_Trending/bo/bokeh创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考