上载CSV文件并在Bokeh Web应用程序中阅读 [英] Upload a CSV file and read it in Bokeh Web app

查看:68
本文介绍了上载CSV文件并在Bokeh Web应用程序中阅读的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个Bokeh绘图应用程序,我需要允许用户上传CSV文件并根据其中的数据修改绘图. 是否可以使用Bokeh的可用窗口小部件来执行此操作? 非常感谢你.

I have a Bokeh plotting app, and I need to allow the user to upload a CSV file and modify the plots according to the data in it. Is it possible to do this with the available widgets of Bokeh? Thank you very much.

推荐答案

尽管没有用于文件输入的本机Bokeh小部件.扩展Bokeh提供的当前工具是完全可行的.该答案将尝试指导您完成创建自定义小部件以及修改bokeh javascript以读取,解析和输出文件的步骤.

Although there is no native Bokeh widget for file input. It is quite doable to extend the current tools provided by Bokeh. This answer will try to guide you through the steps of creating a custom widget and modifying the bokeh javascript to read, parse and output the file.

首先,尽管很多功劳归功于 bigreddot先前关于创建小部件的答案.我只是在他的答案中扩展了文字,以添加文件处理功能.

First though a lot of the credit goes to bigreddot's previous answer on creating the widget. I simply extended the coffescript in his answer to add a file handling function.

现在,我们首先在python上创建一个新的bokeh类,该类将链接到javascript类并保存由文件输入生成的信息.

Now we begin by creating a new bokeh class on python which will link up to the javascript class and hold the information generated by the file input.

models.py

from bokeh.core.properties import List, String, Dict, Int
from bokeh.models import LayoutDOM

class FileInput(LayoutDOM):
__implementation__ = 'static/js/extensions_file_input.coffee'
__javascript__ = './input_widget/static/js/papaparse.js'

value = String(help="""
Selected input file.
""")

file_name = String(help="""
Name of the input file.
""")

accept = String(help="""
Character string of accepted file types for the input. This should be
written like normal html.
""")

data = List(Dict(keys_type=String, values_type=Int), default=[], help="""
List of dictionary containing the inputed data. This the output of the parser.
""")

然后,我们为新的python类创建coffeescript实现.在这个新类中,有一个添加的文件处理程序功能,该功能在文件输入小部件更改时触发.此文件处理程序使用 PapaParse 来解析csv,然后将结果保存在类的data属性中.可以在其网站上下载PapaParse的javascript.

Then we create the coffeescript implementation for our new python class. In this new class, there is an added file handler function which triggers on change of the file input widget. This file handler uses PapaParse to parse the csv and then saves the result in the class's data property. The javascript for PapaParse can be downloaded on their website.

您可以为所需的应用程序和数据格式扩展和修改解析器.

You can extend and modify the parser for your desired application and data format.

extensions_file_input.coffee

import * as p from "core/properties"
import {WidgetBox, WidgetBoxView} from "models/layouts/widget_box"

export class FileInputView extends WidgetBoxView

  initialize: (options) ->
    super(options)
    input = document.createElement("input")
    input.type = "file"
    input.accept = @model.accept
    input.id = @model.id
    input.style = "width:" + @model.width + "px"
    input.onchange = () =>
      @model.value = input.value
      @model.file_name = input.files[0].name
      @file_handler(input)
    @el.appendChild(input)

  file_handler: (input) ->
    file = input.files[0]
    opts =  
      header: true,
      dynamicTyping: true,
      delimiter: ",",
      newline: "\r\n",
      complete: (results) =>
        input.data = results.data
        @.model.data = results.data
    Papa.parse(file, opts)


export class FileInput extends WidgetBox
  default_view: FileInputView
  type: "FileInput"
  @define {
    value: [ p.String ]
    file_name: [ p.String ]
    accept: [ p.String ]
    data : [ p.Array ]
  }

A 回到python端,我们可以将bokeh on_change附加到我们的新输入类上,以在数据属性更改时触发.这将在csv解析完成后发生.此示例展示了所需的交互.

A Back on the python side we can then attach a bokeh on_change to our new input class to trigger when it's data property changes. This will happen after the csv parsing is done. This example showcases the desired interaction.

main.py

from bokeh.core.properties import List, String, Dict, Int
from bokeh.models import LayoutDOM

from bokeh.layouts import column
from bokeh.models import Button, ColumnDataSource
from bokeh.io import curdoc
from bokeh.plotting import Figure

import pandas as pd

from models import FileInput

# Starting data
x = [1, 2, 3, 4]
y = x

source = ColumnDataSource(data=dict(x=x, y=y))

plot = Figure(plot_width=400, plot_height=400)
plot.circle('x', 'y', source=source, color="navy", alpha=0.5, size=20)

button_input = FileInput(id="fileSelect",
                         accept=".csv")


def change_plot_data(attr, old, new):
    new_df = pd.DataFrame(new)
    source.data = source.from_df(new_df[['x', 'y']])


button_input.on_change('data', change_plot_data)

layout = column(plot, button_input)
curdoc().add_root(layout)

此应用程序的.csv文件的示例为.确保csv的末尾没有多余的行.

An example of a .csv file for this application would be. Make sure there is no extra line at the end of the csv.

x,y
0,2
2,3
6,4
7,5
10,25

要正确运行此示例,必须以正确的应用程序文件树格式设置bokeh.

To run this example properly, bokeh must be set up in it's proper application file tree format.

input_widget
   |
   +---main.py
   +---models.py
   +---static
        +---js
            +--- extensions_file_input.coffee
            +--- papaparse.js

要运行此示例,您需要位于最上面的文件上方的目录中,并在终端中执行bokeh serve input_widget.

To run this example, you need to be in the directory above the top most file and execute bokeh serve input_widget in the terminal.

这篇关于上载CSV文件并在Bokeh Web应用程序中阅读的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆