You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Bokeh TapTool点击散点触发对应Thing实例的plot方法生成新图

实现方案

可行性说明

  • 直接调用Thing.plot生成新图的方案完全可行,你的场景下依托Bokeh Server的服务端回调机制即可实现,无需将复杂计算逻辑迁移到前端。
  • 预生成所有Thing.plot实例、点击直接展示的方案也可实现,和前者的实现逻辑几乎一致,仅回调逻辑有少量差异,适合Thing实例数量可控的场景,点击响应速度更快。

具体实现(动态调用Thing.plot版本)

该实现基于Bokeh Server,运行方式为将代码保存为demo.py后执行bokeh serve --show demo.py。

from bokeh.plotting import figure, show
from bokeh.models import TapTool, ColumnDataSource
from bokeh.layouts import column
from bokeh.io import curdoc

class Thing:
    def __init__(self, foo, bar, baz):
        self.foo = foo
        self.bar = bar
        self.baz = baz
    
    def plot(self):
        # 绘制当前Thing实例的全量数据,可保留你的复杂计算逻辑
        fig = figure(width=400, height=300, title=f"当前实例属性详情")
        fig.circle([1,2,3], [self.foo, self.bar, self.baz], size=10)
        return fig

class Collection:
    def __init__(self, things):
        self.things = things
        # 如果用预生成方案,可在这里提前生成所有plot实例
        # self.pre_plots = [thing.plot() for thing in self.things]

    def plot(self, x, y):
        # 构造带索引的数据源,用于点击后匹配对应Thing实例
        xdata = [getattr(th, x) for th in self.things]
        ydata = [getattr(th, y) for th in self.things]
        index_data = list(range(len(self.things)))
        source = ColumnDataSource(data={
            x: xdata,
            y: ydata,
            "index": index_data
        })

        # 配置绘图参数
        title = '{} v {}'.format(x, y)
        fig = figure(title=title, tools=['pan', 'tap', 'box_zoom', 'reset'], width=600, height=400)
        fig.circle(x=x, y=y, source=source, size=12)

        # 点击回调逻辑
        def on_point_click(attr, old, new):
            if not new:
                return
            # 拿到选中点的索引
            selected_idx = new[0]
            # 动态调用Thing.plot
            detail_fig = self.things[selected_idx].plot()
            # 预生成方案替换为下面的代码即可
            # detail_fig = self.pre_plots[selected_idx]
            # 更新页面布局,在散点图下方展示详情图
            layout.children = [layout.children[0], detail_fig]

        # 绑定选中事件回调
        source.selected.on_change('indices', on_point_click)
        return fig

# 初始化测试数据
A = Thing(2, 4, 6)
B = Thing(3, 6, 9)
C = Thing(7, 2, 5)
D = Thing(9, 2, 1)
X = Collection([A, B, C, D])
scatter_fig = X.plot('foo', 'baz')

# 初始化页面布局
layout = column(scatter_fig)
curdoc().add_root(layout)

注意事项

  • 该实现必须运行在Bokeh Server环境下,因为需要执行Python端的计算逻辑,纯静态导出的HTML无法触发Python方法调用。
  • 如果需要点击后弹出独立窗口展示详情图,可在回调中使用bokeh.models.widgets.Div插入打开新窗口的JS代码,将详情图渲染到新窗口即可。

内容的提问来源于stack exchange,提问作者Joe Flip

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 16:15:01