javascript python file upload bokeh

javascript - bokeh scatter 3d



Cargue un archivo CSV y léelo en la aplicación web Bokeh (2)

Tengo una aplicación de trazado de Bokeh, y debo permitir que el usuario cargue un archivo CSV y modifique los gráficos de acuerdo con los datos que contiene. ¿Es posible hacer esto con los widgets disponibles de Bokeh? Muchas gracias.


Por lo que sé, no hay ningún widget nativo de Bokeh que permita subir un archivo.

Sería útil si pudieras aclarar tu configuración actual un poco más. ¿Sus tramas se ejecutan en un servidor de bokeh o simplemente a través de un script de Python que genera las tramas?

Sin embargo, en general, si necesita que esto se exponga a través de un navegador, probablemente desee que algo como Flask ejecute una página que permita al usuario subir un archivo a un directorio que el script del bokeh pueda leer y trazar.


Aunque no hay un widget Bokeh nativo para la entrada de archivos. Es bastante factible ampliar las herramientas actuales proporcionadas por Bokeh. Esta respuesta intentará guiarlo a través de los pasos para crear un widget personalizado y modificar el javascript de bokeh para leer, analizar y generar el archivo.

Primero, aunque gran parte del crédito va a la respuesta anterior de bigreddot para crear el widget. Simplemente extendí el coffescript en su respuesta para agregar una función de manejo de archivos.

Ahora comenzamos creando una nueva clase bokeh en python que enlazará con la clase javascript y mantendrá la información generada por la entrada del archivo.

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

Luego creamos la implementación coffeescript para nuestra nueva clase python. En esta nueva clase, hay una función adicional de controlador de archivos que se activa al cambiar el widget de entrada de archivos. Este manejador de archivos usa PapaParse para analizar el csv y luego guarda el resultado en la propiedad de datos de la clase. El javascript para PapaParse se puede descargar en su sitio web.

Puede ampliar y modificar el analizador para la aplicación y el formato de datos que desee.

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 Atrás en el lado de python, podemos adjuntar un bokeh on_change a nuestra nueva clase de entrada para que se active cuando cambie la propiedad de los datos. Esto sucederá después de que se realice el análisis csv. Este ejemplo muestra la interacción deseada.

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)

Un ejemplo de un archivo .csv para esta aplicación sería. Asegúrese de que no haya una línea adicional al final de la csv.

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

Para ejecutar este ejemplo correctamente, bokeh debe configurarse en su formato de archivo de aplicación apropiado.

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

Para ejecutar este ejemplo, debe estar en el directorio arriba del archivo más superior y ejecutar bokeh serve input_widget en el terminal.