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

Bokeh图像绘图中选区数据求和及RangeTool报错解决咨询

解决Bokeh RangeTool与Image glyph的范围类型不匹配问题

错误原因

你遇到的报错核心是RangeTool的y_range参数仅支持Range1d类型,但Bokeh绘制Image时会自动生成DataRange1d作为轴范围,两者类型不匹配导致验证失败,并非RangeTool和Image glyph本身不兼容。

解决步骤

  1. 手动创建Range1d替代默认范围
    根据你的2D数组的y轴维度(比如数组的行数)手动定义Range1d实例,将其绑定到主绘图的y_range上,替换自动生成的DataRange1d。

  2. 关联RangeTool与自定义Range1d
    创建RangeTool时,将刚才定义的Range1d实例传入y_range参数即可。

  3. 添加选中区域求和的回调逻辑
    通过CustomJS回调监听RangeTool的范围变化,实时计算选中y轴区域内的数据和。

示例代码

from bokeh.plotting import figure, show
from bokeh.models import RangeTool, CustomJS, ColumnDataSource
from bokeh.layouts import column
import numpy as np

# 生成示例2D数组数据
data = np.random.rand(50, 50)  # 50行50列的随机数组
x, y = np.meshgrid(np.linspace(0, 10, 50), np.linspace(0, 10, 50))

# 1. 手动创建Range1d,y范围对应数组的行索引(0到49)
y_range = Range1d(start=0, end=data.shape[0]-1)

# 主绘图,指定y_range为自定义的Range1d
p = figure(y_range=y_range, width=800, height=400)
image = p.image(image=[data], x=0, y=0, dw=10, dh=10, palette="Viridis256")

# 2. 创建RangeTool,关联自定义的y_range
range_tool = RangeTool(y_range=y_range)
range_tool.overlay.fill_color = "navy"
range_tool.overlay.fill_alpha = 0.2

# 创建小图用于显示RangeTool的控制条
select = figure(title="拖动选择Y轴区域", width=800, height=100, y_range=y_range)
select.image(image=[data], x=0, y=0, dw=10, dh=10, palette="Viridis256")
select.yaxis.visible = False
select.add_tools(range_tool)

# 3. 添加求和回调:监听RangeTool的y_range变化,计算选中区域的和
source = ColumnDataSource(data=dict(sum_val=[0]))

callback = CustomJS(args=dict(data=data, y_range=y_range, source=source), code="""
    const start = Math.floor(y_range.start);
    const end = Math.ceil(y_range.end);
    let total = 0;
    // 遍历选中的y轴行,求和
    for (let i = start; i <= end; i++) {
        for (let j = 0; j < data[i].length; j++) {
            total += data[i][j];
        }
    }
    source.data.sum_val[0] = total.toFixed(2);
    source.change.emit();
""")

y_range.js_on_change('start', callback)
y_range.js_on_change('end', callback)

# 添加显示求和结果的文本
p.text(x=1, y=9, text="选中区域总和: ", text_font_size="16pt")
p.text(x=3, y=9, text=source.data['sum_val'], text_font_size="16pt", source=source)

# 布局并显示
show(column(p, select))

关键说明

  • 手动指定Range1d时,要确保范围和你的数据y轴实际范围匹配(比如如果你的Image的y坐标是从0到数组行数,就设置start=0, end=data.shape[0]-1)。
  • 求和逻辑通过CustomJS实现,直接在前端计算,避免后端交互;如果需要后端处理,可以用Bokeh的Server回调。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 15:10:38