是否有可能在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])
答案 0 :(得分:7)
您可以使用CustomJS插入一些JavaScript代码,这些代码将用于更改BoxAnnotation的底部和顶部值。我在这个例子中使用了来自Bokeh的Slider:
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笔记本中完成以下操作:
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))
答案 1 :(得分:4)
从Bokeh 0.11
开始,push_notebook
函数现在可以更新任意Bokeh模型对象。因此,只需在框注释上设置/更新属性,然后调用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])
你可以在这里看到一些笔记本电脑:
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