我正在尝试创建一个简单的散景服务器应用程序,允许用户从<input type="file">
文件选择按钮加载文件。然后,应用程序将绘制用户选择的文件中的数据。下面的代码非常简单,我根本不知道如何将文件信息从文件选择器传递给python。我需要使用python来处理文件I / O而不是html或javascript。
当我在命令行运行bokeh serve --show example.py path/to/input_file
时,我可以正常工作,但我不希望用户每次都指定它。我需要它们能够单击按钮来“上传”文件。此应用程序在本地运行,因此无法上传到服务器或类似的任何内容。
有比<input type="file">
更好的方法吗?
from bokeh.plotting import figure
from bokeh.layouts import layout
from bokeh.models import ColumnDataSource, Div
from bokeh.io import curdoc
desc = Div(text="""
<h1>A simple example</h1>
<input type="file">
<br />""", width=800)
# Create Column Data Source that will be used by the plot
source = ColumnDataSource(data=dict(x=[], y=[]))
p = figure(plot_height=550, plot_width=800, title="", toolbar_location='above')
p.line(x="x", y="y", source=source)
def update():
x_data,y_data = read_file_data(input_file_name) # function to read specific file type
source.data = dict(
x=x_data,
y=y_data,
)
sizing_mode = 'fixed' # 'scale_width' also looks nice with this example
l = layout([
[desc],
[p],
], sizing_mode=sizing_mode)
update()
curdoc().add_root(l)
curdoc().title = "Sample"
答案 0 :(得分:5)
截至Bokeh 0.12.4
,没有内置文件选择器输入小部件。但是create new extensions to Bokeh可以像内置小部件一样无缝地将JS事件连接到Python。
下面的代码是一个模型的超粗略实现,它包装<input type="file">
以将其连接到Python代码。此代码应与Bokeh 0.12.4
及更新版本一起使用。
from bokeh.core.properties import String
from bokeh.io import curdoc
from bokeh.layouts import column
from bokeh.models import Button, LayoutDOM
IMPL = """
import * as p from "core/properties"
import {LayoutDOM, LayoutDOMView} from "models/layouts/layout_dom"
export class FileInputView extends LayoutDOMView
initialize: (options) ->
super(options)
input = document.createElement("input")
input.type = "file"
input.onchange = () =>
@model.value = input.value
@el.appendChild(input)
export class FileInput extends LayoutDOM
default_view: FileInputView
type: "FileInput"
@define {
value: [ p.String ]
}
"""
class FileInput(LayoutDOM):
__implementation__ = IMPL
value = String()
input = FileInput()
def upload():
print(input.value)
button = Button(label="Upload")
button.on_click(upload)
curdoc().add_root(column(input, button))
这导致以下输出:
几乎可以肯定会对此做出改进。对于迭代和协作讨论来说,SO并不是一个好地方,所以如果你对改进这个问题有疑问,我建议将public mailing list作为继续进行的最佳选择。
答案 1 :(得分:0)
我面临同样的任务(将文件传递给Bokeh小部件),但还有一些其他限制(Tornado带有嵌入式Bokeh服务器)。所以下面的代码不是确切的解决方案,但它可以帮助:
Tornado HTTP网页,带有嵌入式Bokeh小部件,可与同一应用程序的其他页面进行通信 https://gist.github.com/Sklavit/c378a18661f0d91918931eba5a1d7553