Доступ к столбцам после загрузки CSV-файла через раскрывающиеся списки - PullRequest
0 голосов
/ 04 февраля 2019

У меня есть приложение-черточка, в котором я пытаюсь загрузить произвольный CSV, а затем получить доступ к столбцам указанного файла данных через раскрывающиеся списки.У меня есть два раскрывающихся списка.Получив доступ к столбцам, я хотел бы вычислить соотношение между ними, а также построить их график.Тем не менее, я застрял, пытаясь выяснить, как получить доступ к загруженным столбцам данных в раскрывающихся списках.У меня есть рабочее приложение Shiny, которое делает это, но я пытаюсь скопировать его с помощью Dash.Я действительно новичок в Dash, так что это может быть простым исправлением.Мой код ниже!

import os
import io
import json
import dash
import base64
import plotly
import datetime
import operator
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import dash_core_components as dcc
import dash_html_components as html
import dash_table_experiments as dte
from dash.dependencies import Input, Output, State

app = dash.Dash()
app.scripts.config.serve_locally = True
app.config['suppress_callback_exceptions'] = True

app.layout = html.Div([

    html.H5("Upload Files"),
    dcc.Upload(
        id='upload-data',
        children=html.Div([
            'Drag and Drop or ',
            html.A('Select Files')
        ]),
        style={
            'width': '15%',
            'height': '60px',
            'lineHeight': '60px',
            'borderWidth': '1px',
            'borderStyle': 'dashed',
            'borderRadius': '5px',
            'textAlign': 'left',
            'margin': '10px'
        },
        multiple=False),

    html.Div([
        html.H5("First Column"),
        dcc.Dropdown(
            id = 'y-dropdown',
            options = [],
        )
    ]),

    html.Div([
        html.H5("Second Column"),
        dcc.Dropdown(
            id = 'x-dropdown',
            options = [],
        )
    ]),    

    html.Br(),
    html.Button(
        id = 'propagate-button',
        n_clicks = 0,
        children = 'Propagate Table Data'
    ),

    html.Br(),
    html.H5("Updated Table"),
    html.Div(
        dte.DataTable(rows = [{}], id = 'table')
    ),

    html.Div(
    dcc.Graph(
        id = 'graph'
        )
    )
])

## Functions 
# File upload function
def parse_contents(contents, filename):
    content_type, content_string = contents.split(',')

    decoded = base64.b64decode(content_string)
    try:
        if 'csv' in filename:
            # Assume that the user uploaded a CSV file
            df = pd.read_csv(
                io.StringIO(decoded.decode('utf-8')))
        elif 'xls' in filename:
            # Assume that the user uploaded an excel file
            df = pd.read_excel(io.BytesIO(decoded))

    except Exception as e:
        print(e)
        return None

    return df

## Callbacks 
# Table creation
@app.callback(Output('table', 'rows'),
              [Input('upload-data', 'contents'),
               Input('upload-data', 'filename')])
def update_output(contents, filename):
    if contents is not None:
        df = parse_contents(contents, filename)
        if df is not None:
            return df.to_dict('records')
        else:
            return [{}]
    else:
        return [{}]

app.css.append_css({
    "external_url": "https://codepen.io/chriddyp/pen/bWLwgP.css"
})

if __name__ == '__main__':
    app.run_server(debug=True)

1 Ответ

0 голосов
/ 06 февраля 2019

Я не думаю, что вы можете создать один обратный вызов с несколькими выходными данными, поэтому вам нужно создать отдельный обратный вызов для каждого раскрывающегося списка и таблицы.Пожалуйста, обратитесь ниже код.

import os
import io
import json
import dash
import base64
import plotly
import datetime
import operator
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import dash_core_components as dcc
import dash_html_components as html
import dash_table_experiments as dte
from dash.dependencies import Input, Output, State

app = dash.Dash()
app.scripts.config.serve_locally = True
app.config['suppress_callback_exceptions'] = True
app.layout = html.Div([

    html.H5("Upload Files"),
    dcc.Upload(
        id='upload-data',
        children=html.Div([
            'Drag and Drop or ',
            html.A('Select Files')
        ]),
        style={
            'width': '15%',
            'height': '60px',
            'lineHeight': '60px',
            'borderWidth': '1px',
            'borderStyle': 'dashed',
            'borderRadius': '5px',
            'textAlign': 'left',
            'margin': '10px'
        },
        multiple=False),

    html.Div([
        html.H5("First Column"),
        dcc.Dropdown(
            id = 'y-dropdown',
            options = [],
        )
    ]),

    html.Div([
        html.H5("Second Column"),
        dcc.Dropdown(
            id = 'x-dropdown',
            options = [],
        )
    ]),    

    html.Br(),
    html.Button(
        id = 'propagate-button',
        n_clicks = 0,
        children = 'Propagate Table Data'
    ),

    html.Br(),
    html.H5("Updated Table"),
    html.Div(
        dte.DataTable(rows = [{}], id = 'table')
    ),

    html.Div(
    dcc.Graph(
        id = 'graph'
        )
    )
])

## Functions 
# File upload function
def parse_contents(contents, filename):
    content_type, content_string = contents.split(',')

    decoded = base64.b64decode(content_string)
    try:
        if 'csv' in filename:
            # Assume that the user uploaded a CSV file
            df = pd.read_csv(io.StringIO(decoded.decode('utf-8')))
        elif 'xls' in filename:
            # Assume that the user uploaded an excel file
            df = pd.read_excel(io.BytesIO(decoded))
    except Exception as e:
        print(e)
        return None
    return df

## Callbacks 
# Table creation
@app.callback(Output('table', 'rows'),
              [Input('upload-data', 'contents'),
               Input('upload-data', 'filename')])
def update_output(contents, filename):
    if contents is not None:
        df = parse_contents(contents, filename)
        columns = df.columns.values.tolist()
        if df is not None:
            return df.to_dict('records')
        else:
            return [{}]
    else:
        return [{}]

# update y-dropdown
@app.callback(Output('y-dropdown', 'options'),
              [Input('upload-data', 'contents'),
               Input('upload-data', 'filename')])
def update_y_dropdown(contents, filename):
    if contents is not None:
        df = parse_contents(contents, filename)
        columns = df.columns.values.tolist()
        if df is not None:
            return [ {'label': x, 'value': x} for x in columns ]
        else:
            return []
    else:
        return []

# update x-dropdown
@app.callback(Output('x-dropdown', 'options'),
              [Input('upload-data', 'contents'),
               Input('upload-data', 'filename')])
def update_x_dropdown(contents, filename):
    if contents is not None:
        df = parse_contents(contents, filename)
        columns = df.columns.values.tolist()
        if df is not None:
            return [ {'label': x, 'value': x} for x in columns ]
        else:
            return []
    else:
        return []

if __name__ == '__main__':
    app.run_server(debug=True)
...