这是我第一次使用bokeh。我正在使用Windows 7,Pycharm作为IDE和python 3.7。我正在尝试使用4 TextInput制作一个表单,以从用户那里获取均值,方差,行数和列数的值,并带有一个Button,当单击该按钮时会生成具有正态分布的随机数的数据框,其中输入均值和方差定义的输入大小。我按照adding widgets link制作了表格,并编写了数据框生成器。但是我很难将其绑定到按钮。为了确保正确处理该事件,我添加了另一个TextInput只是为了在单击按钮时显示均值TextInput的值。代码如下:
from bokeh.models.widgets import TextInput, Button, Div
from bokeh.layouts import layout, column, row
from bokeh.io import curdoc ## to assign callback to widget
from bokeh import events ## for event handling
from bokeh.models import CustomJS
import numpy as np
import pandas as pd
text_input_mean = TextInput(value="0.0", title="Enter mean:")
text_input_vaiance = TextInput(value="0.0", title="Enter variance:")
text_input_rows = TextInput(value="5", title="Enter num rows:")
text_input_columns = TextInput(value="5", title="Enter num columns:")
button = Button(label = "Generate Dataframe", button_type = "success")
text_output = TextInput(title = 'Python result is shown here: ')
div = Div(text="""Making a form with bokeh mainly to handle events.""",
width=500, height=50)
layout = column(div, row(text_input_mean, text_input_vaiance), row(text_input_rows, text_input_columns),
button, text_output)
show(layout)
## Events with no attributes
# button.js_on_event(events.ButtonClick, button_click_handler) # Button click
def my_text_input_handler(attr, old, new):
print("Previous label: " + old)
print("Updated label: " + new)
text_input_mean.on_change("value", my_text_input_handler)
def button_click_handler():
text_output.__setattr__('value', str(text_input_mean.value))
#text_output.value = str(text_input_mean.value)
button.on_click(button_click_handler)
# button.on_click(generate_normal_df)
# curdoc().add_root(layout)
def generate_normal_df(mean, var, x, y):
mean = text_input_mean.value
variance = text_input_vaiance.value
row_num = x
col_num = y
return pd.DataFrame(np.random.normal(loc = mean, scale = variance, size=(row_num, col_num)))
单击按钮后,什么也不会发生!我也查看了控制台,但是也没有。我在同一链接中使用了方法“ my_text_input_handler”,以查看是否更改了text_input_mean的值,但是还是没有变化。我尝试了另一种方法来遵循此link,这就是为什么您可以在我的代码中看到它的原因:
button.on_click(generate_normal_df)
curdoc().add_root(layout)
我稍后会评论。但是当我使用这两行代码时,出现以下错误:
也是这一行:
button.on_click(button_click_handler)
在我的IDE中引起另一个错误。当我使用button_click_handler()时,出现以下错误:
_attach_document中的第609行“ C:\ Users \ E17538 \ anaconda3 \ lib \ site-packages \ bokeh \ model.py” 引发RuntimeError(“模型必须仅由单个文档拥有,%r已在文档中”%(self)) RuntimeError:模型必须仅由一个文档拥有,WidgetBox(id ='1009',...)已存在于文档中
当我不带()使用它时,我再次遇到相同的错误。如果您能指导我如何将处理程序绑定到我的小部件,我将不胜感激。非常感谢。
答案 0 :(得分:1)
您的代码有一些问题。第一个是通常不应同时使用show
和curdoc().add_root(...)
。 show
函数用于显示独立 Bokeh内容,即仅显示静态HTML和JS,而没有Bokeh服务器。但是,curdoc().add_root
通常在Bokeh服务器应用程序的上下文中使用。这两个函数都将它们的值相加,然后传递给新的Bokeh Document
,这是错误的直接原因(模型只能属于一个Document,而您已经将它们添加到了两个)。在这种情况下,正确的解决方法是删除对show
的调用。
此外,on_click
还希望有一个回调函数,该函数需要零个必需参数。但是,您正在传递generate_normal_df
,它具有四个必需的位置参数。这是行不通的(单击按钮时,Bokeh无法知道要传递哪些参数)。如果要使用generate_normal_df
,则需要用lambda
进行包装,或使用functools.partial
来烘焙一些固定的参数值,然后传递结果。