Bokeh 动态改变 BoxAnnotation
Bokeh dynamically changing BoxAnnotation
是否可以在 IPython 的交互功能中更新散景图渲染器。我的代码看起来像:
x = [0, 1, 2, 3, 4]
y = [0, 1, 2, 3, 4]
source = ColumnDataSource(data=dict(x=x, y=y)
f = figure()
f.line(x, y, source=source)
show(f)
def update_func(selected_data):
source.data['y'] = ...
source.push_notebook()
<here I would like to add BoxAnnotation to figure f, and rerender it>
interactive(update_func, selected_data=[0,1,2])
您可以使用 CustomJS 插入一些 JavaScript 代码,用于更改 BoxAnnotation 的底部和顶部值。我在这个例子中使用了来自 Bokeh 的滑块:
from bokeh.io import vform
from bokeh.models import CustomJS, Slider
from bokeh.plotting import figure, show
from bokeh.models import BoxAnnotation
plot = figure(plot_width=300, plot_height=300)
plot.line([0,1],[0,1], line_width=3, line_alpha=0.6)
box_l = BoxAnnotation(plot=plot, top=0.4,
fill_alpha=0.1, fill_color='red')
box_m = BoxAnnotation(plot=plot, bottom = 0.4,top=0.6,
fill_alpha=0.1, fill_color='green')
box_h = BoxAnnotation(plot=plot, bottom=0.6,
fill_alpha=0.1, fill_color='red')
plot.renderers.extend([box_l, box_m, box_h])
callb_low = CustomJS(args=dict(box_l=box_l,box_m=box_m,plot=plot),
code="""
var level = cb_obj.get('value')
box_l.set({"top":level})
box_m.set({"bottom":level})
plot.trigger('change');
""")
callb_high = CustomJS(args=dict(box_m=box_m,box_h=box_h,plot=plot),
code="""
var level = cb_obj.get('value')
box_m.set({"top":level})
box_h.set({"bottom":level})
plot.trigger('change');
""")
slider1 = Slider(start=0.1, end=1, value=0.4, step=.01, title="low",
callback=callb_low)
slider2 = Slider(start=0.1, end=1, value=0.6, step=.01, title="high",
callback=callb_high)
layout = vform(slider1,slider2, plot)
show(layout)
输出将如下所示:
根据 bigreddot 的建议,您可以在 ipython notebooks 中完成以下操作:
from bokeh.io import push_notebook
from bokeh.plotting import figure, show
from bokeh.models import BoxAnnotation
from ipywidgets import interact
p = figure(x_range=(0,1), y_range=(0,1),plot_width=300, plot_height=300)
box_L = BoxAnnotation(plot=p, top=0.4,
fill_alpha=0.1, fill_color='red')
box_M = BoxAnnotation(plot=p, bottom = 0.4,top=0.6,
fill_alpha=0.1, fill_color='green')
box_H = BoxAnnotation(plot=p, bottom=0.6,
fill_alpha=0.1, fill_color='red')
p.renderers.extend([box_L, box_M, box_H])
def update_func(thresh_L=0.4, thresh_H=0.6):
box_L.top = box_M.bottom = thresh_L;
box_M.top = box_H.bottom=thresh_H;
p.renderers.extend([box_L, box_M, box_H])
push_notebook() # note, just a function, not a method on "source"
show(p)
然后在单独的单元格中启动滑块,如:
interact(update_func, thresh_L=(0, 1, 0.1),thresh_H=(0, 1, 0.1))
从 Bokeh 0.11
开始,push_notebook
函数现在可以更新任意 Bokeh 模型对象。所以只需 set/update 框注释上的属性并调用 push_notebook
。您的代码看起来像:
x = [0, 1, 2, 3, 4]
y = [0, 1, 2, 3, 4]
source = ColumnDataSource(data=dict(x=x, y=y)
f = figure()
f.line(x, y, source=source)
show(f)
def update_func(selected_data):
source.data['y'] = ...
# update box annotation (or any other properties) here
push_notebook() # note, just a function, not a method on "source"
interactive(update_func, selected_data=[0,1,2])
你可以在这里看到一些 howto 笔记本:
https://github.com/bokeh/bokeh/blob/master/examples/howto/notebook_comms/Basic%20Usage.ipynb
https://github.com/bokeh/bokeh/blob/master/examples/howto/notebook_comms/Continuous%20Updating.ipynb
https://github.com/bokeh/bokeh/blob/master/examples/howto/notebook_comms/Jupyter%20Interactors.ipynb
是否可以在 IPython 的交互功能中更新散景图渲染器。我的代码看起来像:
x = [0, 1, 2, 3, 4]
y = [0, 1, 2, 3, 4]
source = ColumnDataSource(data=dict(x=x, y=y)
f = figure()
f.line(x, y, source=source)
show(f)
def update_func(selected_data):
source.data['y'] = ...
source.push_notebook()
<here I would like to add BoxAnnotation to figure f, and rerender it>
interactive(update_func, selected_data=[0,1,2])
您可以使用 CustomJS 插入一些 JavaScript 代码,用于更改 BoxAnnotation 的底部和顶部值。我在这个例子中使用了来自 Bokeh 的滑块:
from bokeh.io import vform
from bokeh.models import CustomJS, Slider
from bokeh.plotting import figure, show
from bokeh.models import BoxAnnotation
plot = figure(plot_width=300, plot_height=300)
plot.line([0,1],[0,1], line_width=3, line_alpha=0.6)
box_l = BoxAnnotation(plot=plot, top=0.4,
fill_alpha=0.1, fill_color='red')
box_m = BoxAnnotation(plot=plot, bottom = 0.4,top=0.6,
fill_alpha=0.1, fill_color='green')
box_h = BoxAnnotation(plot=plot, bottom=0.6,
fill_alpha=0.1, fill_color='red')
plot.renderers.extend([box_l, box_m, box_h])
callb_low = CustomJS(args=dict(box_l=box_l,box_m=box_m,plot=plot),
code="""
var level = cb_obj.get('value')
box_l.set({"top":level})
box_m.set({"bottom":level})
plot.trigger('change');
""")
callb_high = CustomJS(args=dict(box_m=box_m,box_h=box_h,plot=plot),
code="""
var level = cb_obj.get('value')
box_m.set({"top":level})
box_h.set({"bottom":level})
plot.trigger('change');
""")
slider1 = Slider(start=0.1, end=1, value=0.4, step=.01, title="low",
callback=callb_low)
slider2 = Slider(start=0.1, end=1, value=0.6, step=.01, title="high",
callback=callb_high)
layout = vform(slider1,slider2, plot)
show(layout)
输出将如下所示:
根据 bigreddot 的建议,您可以在 ipython notebooks 中完成以下操作:
from bokeh.io import push_notebook
from bokeh.plotting import figure, show
from bokeh.models import BoxAnnotation
from ipywidgets import interact
p = figure(x_range=(0,1), y_range=(0,1),plot_width=300, plot_height=300)
box_L = BoxAnnotation(plot=p, top=0.4,
fill_alpha=0.1, fill_color='red')
box_M = BoxAnnotation(plot=p, bottom = 0.4,top=0.6,
fill_alpha=0.1, fill_color='green')
box_H = BoxAnnotation(plot=p, bottom=0.6,
fill_alpha=0.1, fill_color='red')
p.renderers.extend([box_L, box_M, box_H])
def update_func(thresh_L=0.4, thresh_H=0.6):
box_L.top = box_M.bottom = thresh_L;
box_M.top = box_H.bottom=thresh_H;
p.renderers.extend([box_L, box_M, box_H])
push_notebook() # note, just a function, not a method on "source"
show(p)
然后在单独的单元格中启动滑块,如:
interact(update_func, thresh_L=(0, 1, 0.1),thresh_H=(0, 1, 0.1))
从 Bokeh 0.11
开始,push_notebook
函数现在可以更新任意 Bokeh 模型对象。所以只需 set/update 框注释上的属性并调用 push_notebook
。您的代码看起来像:
x = [0, 1, 2, 3, 4]
y = [0, 1, 2, 3, 4]
source = ColumnDataSource(data=dict(x=x, y=y)
f = figure()
f.line(x, y, source=source)
show(f)
def update_func(selected_data):
source.data['y'] = ...
# update box annotation (or any other properties) here
push_notebook() # note, just a function, not a method on "source"
interactive(update_func, selected_data=[0,1,2])
你可以在这里看到一些 howto 笔记本:
https://github.com/bokeh/bokeh/blob/master/examples/howto/notebook_comms/Basic%20Usage.ipynb
https://github.com/bokeh/bokeh/blob/master/examples/howto/notebook_comms/Continuous%20Updating.ipynb
https://github.com/bokeh/bokeh/blob/master/examples/howto/notebook_comms/Jupyter%20Interactors.ipynb