散景:无法从 doc.add_periodic_callback() 触发 ColumnDataSource 上的 js_on_change
Bokeh: Failed to trigger js_on_change on ColumnDataSource from doc.add_periodic_callback()
我正在尝试从散景服务器中的另一个线程更新坡度 y_intercept。但是我无法触发js_on_change,似乎连javascript代码都没有生成。有人可以告诉我这里出了什么问题吗?这是整个代码(更新为使用 add_periodic_callback()):
#!/usr/bin/env python3
from bokeh.layouts import column
from bokeh.models import ColumnDataSource, Slope, CustomJS
from bokeh.plotting import figure
from bokeh.server.server import Server
import pandas as pd
source = ColumnDataSource()
n = 0
def update():
global n
source.data = pd.DataFrame({"y": [n]})
print(f"{source.data=}")
n += 1
def bkapp(doc):
plot = figure(y_range=(-10, 10))
plot.line([-10, 10], [-10, 10])
slope = Slope(gradient=0, y_intercept=0, line_color='black')
plot.add_layout(slope)
source.js_on_change('data', CustomJS(
args=dict(ds=source, slopes=slope), code="""
console.log("whereismycode");
slope.y_intercept = ds.data["y"][0];
"""
))
doc.add_root(plot)
doc.add_periodic_callback(update, 5000)
server = Server({'/': bkapp}, port=5103, num_procs=1)
server.start()
if __name__ == '__main__':
print(f'address = {server.address}, port = {server.port}')
server.io_loop.add_callback(server.show, "/")
server.io_loop.start()
这是工作代码。正如 Tim Roberts 指出的那样,问题在于 bokeh doc 不知道数据源。一个 hacky 解决方案是将它附加到隐藏的字形。 @bigreddot,也许有专门用于此目的的特殊方法?
#!/usr/bin/env python3
from bokeh.layouts import column
from bokeh.models import ColumnDataSource, Slope, CustomJS, DataTable
from bokeh.plotting import figure
from bokeh.server.server import Server
from bokeh.layouts import column
import pandas as pd
source = ColumnDataSource()
n = 0
def update():
global n
source.data = pd.DataFrame({"y": [n]})
print(f"{source.data=}")
n += 1
def bkapp(doc):
plot = figure(y_range=(-10, 10))
plot.line([-10, 10], [-10, 10])
slope = Slope(gradient=0, y_intercept=0, line_color='black')
plot.add_layout(slope)
table = DataTable(source=source, visible=False)
source.js_on_change('data', CustomJS(
args=dict(ds=source, slope=slope), code="""
console.log("whereismycode");
slope.y_intercept = ds.data["y"][0];
"""
))
doc.add_root(column([plot, table]))
doc.add_periodic_callback(update, 5000)
server = Server({'/': bkapp}, port=5103, num_procs=1)
server.start()
if __name__ == '__main__':
print(f'address = {server.address}, port = {server.port}')
server.io_loop.add_callback(server.show, "/")
server.io_loop.start()
纯粹基于问题,完全如上文所述,根本不需要CDS来更新斜率,加一个就是over-complication。这是我要写的代码:
import pandas as pd
from bokeh.layouts import column
from bokeh.models import ColumnDataSource, CustomJS, Slope
from bokeh.plotting import figure
from bokeh.server.server import Server
n = 0
def bkapp(doc):
plot = figure(y_range=(-10, 10))
plot.line([-10, 10], [-10, 10])
slope = Slope(gradient=0, y_intercept=0, line_color='black')
plot.add_layout(slope)
def update():
global n
slope.y_intercept = n
n += 1
doc.add_root(plot)
doc.add_periodic_callback(update, 5000)
server = Server({'/': bkapp}, port=5103, num_procs=1)
server.start()
if __name__ == '__main__':
print(f'address = {server.address}, port = {server.port}')
server.io_loop.add_callback(server.show, "/")
server.io_loop.start()
顺便说一句,请注意,如果您希望一次拥有多个 user/session,那么就不会有任何“全局”Bokeh 模型(例如,您的情况下的全局 CDS) . bkapp
函数必须 return 每个会话 完全唯一的新对象集 。
我正在尝试从散景服务器中的另一个线程更新坡度 y_intercept。但是我无法触发js_on_change,似乎连javascript代码都没有生成。有人可以告诉我这里出了什么问题吗?这是整个代码(更新为使用 add_periodic_callback()):
#!/usr/bin/env python3
from bokeh.layouts import column
from bokeh.models import ColumnDataSource, Slope, CustomJS
from bokeh.plotting import figure
from bokeh.server.server import Server
import pandas as pd
source = ColumnDataSource()
n = 0
def update():
global n
source.data = pd.DataFrame({"y": [n]})
print(f"{source.data=}")
n += 1
def bkapp(doc):
plot = figure(y_range=(-10, 10))
plot.line([-10, 10], [-10, 10])
slope = Slope(gradient=0, y_intercept=0, line_color='black')
plot.add_layout(slope)
source.js_on_change('data', CustomJS(
args=dict(ds=source, slopes=slope), code="""
console.log("whereismycode");
slope.y_intercept = ds.data["y"][0];
"""
))
doc.add_root(plot)
doc.add_periodic_callback(update, 5000)
server = Server({'/': bkapp}, port=5103, num_procs=1)
server.start()
if __name__ == '__main__':
print(f'address = {server.address}, port = {server.port}')
server.io_loop.add_callback(server.show, "/")
server.io_loop.start()
这是工作代码。正如 Tim Roberts 指出的那样,问题在于 bokeh doc 不知道数据源。一个 hacky 解决方案是将它附加到隐藏的字形。 @bigreddot,也许有专门用于此目的的特殊方法?
#!/usr/bin/env python3
from bokeh.layouts import column
from bokeh.models import ColumnDataSource, Slope, CustomJS, DataTable
from bokeh.plotting import figure
from bokeh.server.server import Server
from bokeh.layouts import column
import pandas as pd
source = ColumnDataSource()
n = 0
def update():
global n
source.data = pd.DataFrame({"y": [n]})
print(f"{source.data=}")
n += 1
def bkapp(doc):
plot = figure(y_range=(-10, 10))
plot.line([-10, 10], [-10, 10])
slope = Slope(gradient=0, y_intercept=0, line_color='black')
plot.add_layout(slope)
table = DataTable(source=source, visible=False)
source.js_on_change('data', CustomJS(
args=dict(ds=source, slope=slope), code="""
console.log("whereismycode");
slope.y_intercept = ds.data["y"][0];
"""
))
doc.add_root(column([plot, table]))
doc.add_periodic_callback(update, 5000)
server = Server({'/': bkapp}, port=5103, num_procs=1)
server.start()
if __name__ == '__main__':
print(f'address = {server.address}, port = {server.port}')
server.io_loop.add_callback(server.show, "/")
server.io_loop.start()
纯粹基于问题,完全如上文所述,根本不需要CDS来更新斜率,加一个就是over-complication。这是我要写的代码:
import pandas as pd
from bokeh.layouts import column
from bokeh.models import ColumnDataSource, CustomJS, Slope
from bokeh.plotting import figure
from bokeh.server.server import Server
n = 0
def bkapp(doc):
plot = figure(y_range=(-10, 10))
plot.line([-10, 10], [-10, 10])
slope = Slope(gradient=0, y_intercept=0, line_color='black')
plot.add_layout(slope)
def update():
global n
slope.y_intercept = n
n += 1
doc.add_root(plot)
doc.add_periodic_callback(update, 5000)
server = Server({'/': bkapp}, port=5103, num_procs=1)
server.start()
if __name__ == '__main__':
print(f'address = {server.address}, port = {server.port}')
server.io_loop.add_callback(server.show, "/")
server.io_loop.start()
顺便说一句,请注意,如果您希望一次拥有多个 user/session,那么就不会有任何“全局”Bokeh 模型(例如,您的情况下的全局 CDS) . bkapp
函数必须 return 每个会话 完全唯一的新对象集 。