I am trying to take file contents using the upload content component. Instead of putting directly into the table as I’ve seen in some dash recipes, I want to store the data frame into a hidden div so it can be passed around to multiple callbacks (table rows, dropdown options, and graph figure). I’ve tried using the to_json method as described in the user guide but the issue is that this data frame is not globally defined at runtime, it is dependent upon the upload file contents. Below is my code to see what i’ve tried. Any help would be great!
##############################################################
#Imports
import dash
import dash_html_components as html
import dash_core_components as dcc
import dash_table_experiments as dtable
from dash.dependencies import Input, Output, State
import plotly
import plotly.graph_objs as go
import pandas as pd
import numpy as np
import json
import datetime
import operator
import os
import base64
import io
##############################################################
#Define app
app = dash.Dash()
app.scripts.config.serve_locally = True
app.config['suppress_callback_exceptions'] = True
##############################################################
#App layout
app.layout = html.Div([
################################
html.Div(id='temp_value', style={'display': 'none'}),
html.H5("Upload file"),
dcc.Upload(
id = 'upload_data',
children = html.Div([
'Drag and Drop or ',
html.A('Select Files')
]),
style = {
'width': '100%',
'height': '60px',
'lineHeight': '60px',
'borderWidth': '1px',
'borderStyle': 'dashed',
'borderRadius': '5px',
'textAlign': 'center',
'margin': '10px'
},
multiple = False),
#################################
html.Br(),
html.Div(dtable.DataTable(rows = [{}], id = 'table', row_selectable=True, filterable = True, sortable = True,
editable = False, selected_row_indices = [])),
#################################
html.Div([
html.H5("X Dropdown"),
dcc.Dropdown(
id = 'x_dropdown',
options = [],
value = ''
)
]),
html.Div([
html.H5("Y Dropdown"),
dcc.Dropdown(
id = 'y_dropdown',
options = [],
value = ''
)
]),
html.Div(
dcc.Graph(
id = 'graph'
)
)
])
##############################################################
#Functions
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
@app.callback(Output('temp_value', 'children'),
[Input('upload_data', 'contents'),
Input('upload_data', 'filename')])
def update_output(contents, filename):
if contents is not None:
df = parse_contents(contents, filename)
return df.to_json(date_format = 'iso', orient = 'split')
else:
return [{}]
@app.callback(Output('table', 'rows'),
[Input('temp_value', 'children')])
def update_table(temp_df):
temp_df = pd.read_json(temp_df, orient = 'split')
if temp_df is not None:
return temp_df.to_dict('records')
else:
return [{}]
@app.callback(Output('x_dropdown', 'options'),
[Input('temp_value', 'children')])
def update_x_dropdown(temp_df):
temp_df = pd.read_json(temp_df, orient = 'split')
return [{'label': i, 'value': i} for i in temp_df.columns]
@app.callback(Output('y_dropdown', 'options'),
[Input('temp_value', 'children')])
def update_y_dropdown(temp_df):
temp_df = pd.read_json(temp_df, orient = 'split')
return [{'label': j, 'value': j} for j in temp_df.columns]
@app.callback(
Output('graph', 'figure'),
[Input('x_dropdown', 'value'),
Input('y_dropdown', 'value'),
Input('temp_value', 'children')])
def update_graph(xaxis_column_name, yaxis_column_name, temp_df):
temp_df = pd.read_json(temp_df, orient = 'split')
figure = {
'data': [
go.Scatter(
x = temp_df[xaxis_column_name],
y = temp_df[yaxis_column_name],
mode = 'markers'
)
],
'layout': go.Layout(
xaxis = {'title': xaxis_column_name},
yaxis = {'title': yaxis_column_name},
hovermode = 'closest'
)
}
return figure
if __name__ == '__main__':
app.run_server(debug=True)