我创建了一个名为ed_montecarlo的函数,它运行具有一定数量迭代的montecarlo模拟,并将结果作为带有多列的pandas数据框返回(这里并不是所有列都使用。)目前我正在尝试将其链接到一个绘图使用Bokeh并有一个滑块,当更改时将使用滑块的新值重新运行该功能。
我的代码如下:
def modify_doc(doc):
source = ColumnDataSource(ed_montecarlo(num=1000))
TOOLS = "pan,wheel_zoom,box_zoom,reset,save"
iter_scatter= figure(x_axis_label='Iteration Number', y_axis_label='Margin', title='Scatter Plot of Iterrations',
tools=TOOLS, plot_height=400, plot_width=550)
iter_scatter.yaxis[0].formatter = NumeralTickFormatter(format="$0.00")
dots = iter_scatter.scatter(x='index', y='Margin', source=source, fill_alpha=.5, line_color=None,
hover_fill_color='firebrick', hover_alpha=.9, hover_line_color=None, size=10)
iter_scatter.line(x='index', y='Median Margin', source=source, line_color='cyan', line_width=5, line_alpha=0.8)
band = Band(base='index', lower='25th Margin', upper='75th Margin', source=source, level='underlay',
fill_alpha=0.3, line_width=3, line_alpha=.8, line_color='cyan', fill_color='cyan')
iter_scatter.add_layout(band)
iter_scatter.add_tools(HoverTool(tooltips=[('Iterration', '@index'),
('Margin', '$@Margin{%0.2f}')],
formatters={'Margin': 'printf',},
renderers = [dots], mode='mouse'))
def callback(attr, old, new):
num = iter_slider.value
iter_slider = Slider(start=100, end=5000, step=100, value=1000, title='Number of Iterations')
iter_slider.on_change('value', callback)
doc.add_root(column(iter_slider, iter_scatter))
show(modify_doc)
当我运行上面的代码时,散点图使用1000次迭代正确显示,但是当我移动滑块时,它不会重新运行蒙特卡罗函数并更新绘图。我错过了什么?我一直在敲打我的脑袋。
你的回调没有做任何实际的工作。您将滑块的值分配给局部变量num
(根本没有其他影响),然后立即退出回调。如果要更新绘图,则必须更新数据源。你还没有说过ed_montecarlo
返回的类型是什么,但它会有所不同
def callback(attr, old, new):
source.data = ed_montecarlo(num=iter_slider.value)
假设ed_montecarlo
返回一个合适的Python dict
。如果没有,你需要转换它,但必须是一个python dict,CDS列名称作为键,数据数组作为值。