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

如何在Bokeh中通过回调实现x轴范围变化时调整y轴范围?

问题描述

我希望每次x轴范围变化时,更改y轴的可见范围。但当前代码似乎无法正常工作:平移或修改x轴范围时,回调函数未被触发,或是回调函数存在问题?

现有代码

import numpy as np
from bokeh.plotting import figure, show
from bokeh.models import CustomJS

x = list(range(100))
y = list(np.random.randint(-10, 10, 100))
y = np.cumsum(y)
p1 = figure(title="Random", width=600, height=600)
p1.line(x, y, color="red")

callback = CustomJS(args=dict(yrange=p1.y_range), code="""
           yrange.start=-10;
           yrange.end=10;""")
                
p1.x_range.js_on_change("end", callback)

show(p1)
问题原因与解决方法

核心问题

你只监听了x_range的end属性变化,但平移或缩放x轴时,start和end会同时更新,只监听单个属性会导致部分操作无法触发回调。以下分两种场景给出解决方案:


场景1:固定y轴范围为-10到10

同时监听x_range的start和end属性,确保任何x轴范围修改都能触发回调:

import numpy as np
from bokeh.plotting import figure, show
from bokeh.models import CustomJS

x = list(range(100))
y = list(np.random.randint(-10, 10, 100))
y = np.cumsum(y)
p1 = figure(title="Random", width=600, height=600)
p1.line(x, y, color="red")

callback = CustomJS(args=dict(yrange=p1.y_range), code="""
    yrange.start = -10;
    yrange.end = 10;
""")

# 同时监听start和end的变化
p1.x_range.js_on_change("start", callback)
p1.x_range.js_on_change("end", callback)

show(p1)

场景2:根据当前x轴范围内的y值动态调整y轴范围

如果需要自动适配当前x区间内的y值极值,需要将x、y数据传入JS回调,在前端筛选并计算范围:

import numpy as np
from bokeh.plotting import figure, show
from bokeh.models import CustomJS

x = list(range(100))
y = list(np.random.randint(-10, 10, 100))
y = np.cumsum(y)
p1 = figure(title="Random", width=600, height=600)
p1.line(x, y, color="red")

# 传入x、y数组供JS回调使用
callback = CustomJS(args=dict(yrange=p1.y_range, x=x, y=y), code="""
    const xStart = cb_obj.start;
    const xEnd = cb_obj.end;
    
    // 筛选当前x范围内的y值
    const filteredY = y.filter((_, idx) => x[idx] >= xStart && x[idx] <= xEnd);
    
    if (filteredY.length > 0) {
        const minY = Math.min(...filteredY);
        const maxY = Math.max(...filteredY);
        // 添加少量边距避免图形紧贴轴边界
        yrange.start = minY - 1;
        yrange.end = maxY + 1;
    }
""")

# 监听x_range的所有范围变化
p1.x_range.js_on_change("start", callback)
p1.x_range.js_on_change("end", callback)

show(p1)
关键说明
  • Bokeh中x_range的范围变化会同时修改start和end属性,仅监听其中一个会导致回调触发不完整。
  • 动态计算y轴范围时,必须将原始x、y数据传递给JS回调,才能在前端完成数据筛选和极值计算。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 16:55:22