Python 如何组合bokeh小部件和html标记?

Python 如何组合bokeh小部件和html标记?,python,bokeh,Python,Bokeh,我用bokeh制作了一个简单的表单,如下所示: from bokeh.io import output_file, show from bokeh.layouts import widgetbox from bokeh.models.widgets import TextInput, Button, Div from bokeh.layouts import layout, column, row from bokeh.io import curdoc ## to assign callback

我用bokeh制作了一个简单的表单,如下所示:

from bokeh.io import output_file, show
from bokeh.layouts import widgetbox
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)


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)


def generate_normal_df():
    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)))

button.on_click(button_click_handler)
curdoc().add_root(layout)

# this part causes error!
<html>
<b> End of page </b>
# a tag goes here
<\html>

我想为用户制作一个可下载的链接,当用户点击按钮时,可以下载excel表格。我尝试向bokeh表单添加一个htmla标记,并将其href属性设置为服务器上Excel工作表的地址。但我知道这会导致SyntaxError

代码如下:

from bokeh.io import output_file, show
from bokeh.layouts import widgetbox
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)


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)


def generate_normal_df():
    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)))

button.on_click(button_click_handler)
curdoc().add_root(layout)

# this part causes error!
<html>
<b> End of page </b>
# a tag goes here
<\html>
从bokeh.io导入输出文件,显示
从bokeh.layouts导入widgetbox
从bokeh.models.widgets导入文本输入、按钮、Div
从bokeh.layouts导入布局、列、行
从bokeh.io导入curdoc###将回调分配给小部件
从bokeh导入事件##用于事件处理
从bokeh.models导入CustomJS
将numpy作为np导入
作为pd进口熊猫
text\u input\u mean=text输入(value=“0.0”,title=“输入平均值:”)
text\u input\u vaiance=text输入(value=“0.0”,title=“输入方差:”)
text\u input\u rows=text输入(value=“5”,title=“输入num rows:”)
text\u input\u columns=text输入(value=“5”,title=“输入num columns:”)
按钮=按钮(标签=“生成数据帧”,按钮类型=“成功”)
text_output=TextInput(title='此处显示Python结果:')
div=div(text=“”与bokeh制作表单主要用于处理事件。“”,
宽度=500,高度=50)
布局=列(div,row(文本输入平均值,文本输入值),row(文本输入行,文本输入列),
按钮,文本(U输出)
def my_text_input_处理程序(属性、旧、新):
打印(“以前的标签:+旧的)
打印(“更新标签:+新)
文本输入的意思。在更改时(“值”,我的文本输入处理程序)
def按钮\单击\处理程序():
文本输出。uuu设置属性(值),str(文本输入平均值))
text\u output.value=str(text\u input\u mean.value)
def生成_正常_df():
平均值=文本\输入\平均值
方差=文本\输入\值
行数=x
col_num=y
返回pd.DataFrame(np.random.normal(loc=平均值,scale=方差,size=(行数,列数)))
按钮。单击时(按钮单击处理程序)
curdoc().添加根目录(布局)
#这部分会导致错误!
页尾
#标签在这里
我还没有实现如何获取生成的excel工作表的地址。我的想法是将数据框保存为Excel工作表;通过使用os库获取其地址,并设置标记的href属性。但是这个.python表单中的html部分会导致错误


你能告诉我该怎么解决吗?有没有一种方法可以用bokeh格式编写html?例如,a标记不能作为小部件使用。感谢您的关注。

您可以为按钮创建一个纯JS回调,并将数据作为JSON下载,而无需像下面这样涉及服务器:

from bokeh.io import show
from bokeh.plotting import figure
from bokeh import events
from bokeh.models import CustomJS, Div, Button, RadioButtonGroup
from bokeh.layouts import column, row
import numpy as np

data = {'mean': np.arange(10), 'variance': np.random.random(10) }
button = Button(label = "Download JSON", button_type = "success")

js_download = """
var filename = 'results.json';
var blob = new Blob([JSON.stringify(data)], { type: 'text/json;charset=utf-8;' });
if (navigator.msSaveBlob) { // IE 10+
navigator.msSaveBlob(blob, filename);
} else {
var link = document.createElement("a");
if (link.download !== undefined) { // feature detection
    // Browsers that support HTML5 download attribute
    var url = URL.createObjectURL(blob);
    link.setAttribute("href", url);
    link.setAttribute("download", filename);
    link.style.visibility = 'hidden';
    document.body.appendChild(link);
    link.click();
    document.body.removeChild(link); } }"""

button.callback = CustomJS(args = dict(data = data), code = js_download)
show(button)

只需将正确的对象传递给回调,即可从中提取数据(例如,您的数据帧)。如果您希望从服务器获取数据,那么最简单的方法是在回调中使用JS fetch()方法,如中所示。在这种情况下,您需要以如下方式运行代码:
bokeh-serve——显示我的应用程序目录
,您需要一个
/static
目录,在那里保存文件并将其返回到浏览器。或者,您可以在JS回调中使用类似AjaxDataSource或纯AJAX的东西从服务器获取json,并让用户下载,如上面的示例所示(在Bokeh v1.0.4上测试)。

您可以为按钮创建纯JS回调,并将数据作为json下载,而无需像下面这样涉及服务器:

from bokeh.io import show
from bokeh.plotting import figure
from bokeh import events
from bokeh.models import CustomJS, Div, Button, RadioButtonGroup
from bokeh.layouts import column, row
import numpy as np

data = {'mean': np.arange(10), 'variance': np.random.random(10) }
button = Button(label = "Download JSON", button_type = "success")

js_download = """
var filename = 'results.json';
var blob = new Blob([JSON.stringify(data)], { type: 'text/json;charset=utf-8;' });
if (navigator.msSaveBlob) { // IE 10+
navigator.msSaveBlob(blob, filename);
} else {
var link = document.createElement("a");
if (link.download !== undefined) { // feature detection
    // Browsers that support HTML5 download attribute
    var url = URL.createObjectURL(blob);
    link.setAttribute("href", url);
    link.setAttribute("download", filename);
    link.style.visibility = 'hidden';
    document.body.appendChild(link);
    link.click();
    document.body.removeChild(link); } }"""

button.callback = CustomJS(args = dict(data = data), code = js_download)
show(button)

只需将正确的对象传递给回调,即可从中提取数据(例如,您的数据帧)。如果您希望从服务器获取数据,那么最简单的方法是在回调中使用JS fetch()方法,如中所示。在这种情况下,您需要以如下方式运行代码:
bokeh-serve——显示我的应用程序目录
,您需要一个
/static
目录,在那里保存文件并将其返回到浏览器。或者,您可以在JS回调中使用类似AjaxDataSource或纯AJAX的东西从服务器获取json,并让用户下载它,如上面的示例所示(在Bokeh v1.0.4上测试)。

如果您展示您现有的尝试,这将使这个问题更容易回答。目前还不清楚你做了什么以及你需要什么帮助。@LieRyan我刚刚在问题中添加了代码,并做了更多解释。如果你展示了你现有的尝试,这将使这个问题更容易回答。目前还不清楚你做了什么以及你需要什么帮助。@LieRyan我只是在问题中添加了代码,并做了更多解释。