上传 CSV 文件并在 Bokeh Web 应用程序中读取

Posted

技术标签:

【中文标题】上传 CSV 文件并在 Bokeh Web 应用程序中读取【英文标题】:Upload a CSV file and read it in Bokeh Web app 【发布时间】:2017-04-09 05:12:06 【问题描述】:

我有一个散景绘图应用程序,我需要允许用户上传 CSV 文件并根据其中的数据修改绘图。 是否可以使用 Bokeh 的可用小部件来做到这一点? 非常感谢。

【问题讨论】:

【参考方案1】:

虽然没有用于文件输入的原生 Bokeh 小部件。扩展 Bokeh 提供的当前工具是完全可行的。此答案将尝试指导您完成创建自定义小部件和修改散景 javascript 以读取、解析和输出文件的步骤。

虽然很多功劳归于bigreddot's previous answer 创建小部件。我只是在他的回答中扩展了咖啡脚本以添加文件处理功能。

现在我们开始在 python 上创建一个新的散景类,它将链接到 javascript 类并保存文件输入生成的信息。

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,然后将结果保存在类的数据属性中。 PapaParse 的 javascript 可以在他们的网站上下载。

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

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 ]
  

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

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 末尾没有多余的行。

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

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

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

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

【讨论】:

很好,你!为了接受任何类型的数据,将 models.py 中的 value_type 参数从“Int”调整为“Any”。【参考方案2】:

据我所知,Bokeh 没有本地小部件可以允许文件上传。

如果您能进一步阐明您当前的设置,将会很有帮助。您的绘图是在散景服务器上运行还是仅通过生成绘图的 Python 脚本运行?

不过,一般来说,如果您需要通过浏览器公开此内容,您可能需要运行类似 Flask 的页面,该页面允许用户将文件上传到目录,然后散景脚本可以读取和绘制该目录。

【讨论】:

当前设置是一个散景服务器进行绘图。可以使用多个滑块更改绘图(y 值是预测)。该应用程序基于对约 10 个特征的预测。假设您有 100 个样本并且想要 100 个预测,我需要添加一个 CSV 上传选项,以便您可以直接获取要下载的概率值。我是散景、JS 的新手,所以我正在寻找一个可以添加到散景应用页面底部的简单小部件。 不幸的是,知情人士 @ssm,抱歉我之前的评论发布得太早了!据我所知,没有这样的小部件。您需要做的是使用另一个 Python 应用程序为页面上的其他元素提供服务以接受文件上传。使用像 Flask 这样的简单网络服务器框架应该很容易实现,它返回整个页面,有一个嵌入 Bokeh 服务器输出的 和另一个包含用户上传选项的 。

以上是关于上传 CSV 文件并在 Bokeh Web 应用程序中读取的主要内容,如果未能解决你的问题,请参考以下文章

Flutter web:将 CSV 文件存储到 Firebase 存储,无需从计算机上传

如何使用 Python 在 myBucket 中上传 CSV 文件并在 S3 AWS 中读取文件

Kentico,带有用于上传 CSV 的 Web 部件的模块

使用 D3.js 解析上传的 CSV 文件

通过我的 Azure Web 应用上传文件时超时

如何从邮递员获取 CSV 文件并在 NestJs 上转换为数组