Pass file information from html file selector input to python and bokeh

空扰寡人 提交于 2019-12-24 00:42:29

问题


I'm trying to create a simple bokeh server application that allows a user to load a file from a <input type="file"> file selection button. The app will then plot the data from the file that the user selected. The code below is very simplistic, and I simply don't know how to pass the file information from the file selector to python. I need to use python to handle the file I/O and not html or javascript.

I can get it to work just fine when I run bokeh serve --show example.py path/to/input_file at the command line, but I don't want the user to specify this each time. I need them to be able to click a button to "upload" the file. This application is running locally, so there is no uploading to a server or anything like that.

Is there a better method than <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"

回答1:


Maintainer note: CoffeeScript support is deprecated in Bokeh and will be removed entirely in Bokeh 2.0. This example would need to be re-written in JavaScript or TypeScript

As of Bokeh 0.12.4, there's no built-in file chooser input widget. But it is possible to create new extensions to Bokeh that work as seamlessly as the built-in widgets to connect JS events to Python.

The code below is a super-rough implementation of a model that wraps an <input type="file"> to hook it up to Python code. This code should work with Bokeh 0.12.4 and newer.

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))

This results in the output below:

There are almost certainly improvements that could be made to this. SO is not really a good place for iterative and collaborative discussion, so if you have questions about improving this, I'd suggest the project Discourse list as the best place to continue.




回答2:


I faced the same task (pass files to Bokeh widget) but with some other restrictions (Tornado with embedded Bokeh server). So the code below is not the exact solution but it can help:

Tornado HTTP web page with embedded Bokeh widget which communicates with other page of the same application https://gist.github.com/Sklavit/c378a18661f0d91918931eba5a1d7553



来源:https://stackoverflow.com/questions/39206400/pass-file-information-from-html-file-selector-input-to-python-and-bokeh

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!