Dear Forum,
I’m working on a multi-page Dash app, where the user selects a .csv from a drop-down (home page), and this is supposed to generate graphs, etc. on the home page as well as other pages. The problem I’m encountering is that as soon as I move off any given “page”, all data is lost and I have to re-select (i.e. reload) the file from the list. I’ve attempted to use the “hidden div” hack, but that didn’t seem to work. I’m quite certain I’m doing something wrong or missing something. I’m posting my code below for each page and hopefully, someone has gone through this before.
the .csv test file contains two columns: “Brand” with x number of categories (i.e. Microsoft, IBM, etc.), and another column called “var_1” with a numerical “score” for each brand.
Thank you in advance for your assistance!
app.py
import dash
external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']
app = dash.Dash(__name__, external_stylesheets=external_stylesheets)
server = app.server
app.config.suppress_callback_exceptions = True
Index.py
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output, State
from os import listdir
from os.path import isfile, join
from dash.exceptions import PreventUpdate
import pandas as pd
from app import app
from layouts import layout1, layout2
import callbacks
pathway = '/yourpathtotheappfolder...'
files = [f for f in listdir(pathway) if isfile(join(pathway, f))] #this iterates through the files in the folder
app.layout = html.Div([
dcc.Location(id='url', refresh=False),
html.Div(id='intermediate-value', style={'display': 'none'}), #hidden div, doesn't seem to work
html.Div([
dcc.Link('Home', href='/app1', className="tab first",), #link to page 1 "Home"
dcc.Link('Page 1', href='/app2', className="tab",), #link to another page "Page 1"
], className="row all-tabs",
),
dcc.Dropdown(
id='file_select',
options=[
{'label': i, 'value': i} for i in files
],
multi=False
),
# code for the brand select dropdown
dcc.Dropdown(
id="select_brand",
options=[],
multi=False,
),
html.Div(id='page-content')
])
@app.callback(Output('intermediate-value', 'children'), [Input('file_select', 'value')])
def clean_data(value):
# going to just upload that csv as a dataframe to the hidden div!
cleaned_df = pd.read_csv(value)
return cleaned_df.to_json() # or, more generally, json.dumps(cleaned_df)
@app.callback(Output('page-content', 'children'),
[Input('url', 'pathname')])
def display_page(pathname):
if pathname == '/app1':
return layout1
elif pathname == '/app2':
return layout2
else:
return '404'
if __name__ == '__main__':
app.run_server(debug=True)
Callbacks.py
# Specify the callbacks for the app
from dash.dependencies import Input, Output
from app import app
import dash_table
import pandas as pd
import numpy as np
import plotly.graph_objs as go
import plotly
# this is for the dynamic dropdown field to select brand (which for now does nothing)
@app.callback(Output('select_brand', 'options'),
[Input('file_select','value')])
def update_dropdown(file):
if file is not None:
df = pd.read_csv(file)
columns = df.Brand.values.tolist()
columns = list(set(columns))
if df is not None:
return [{'label': x, 'value': x} for x in columns]
else:
return []
else:
return []
#This populates the graph
@app.callback([Output('table', 'children'),
Output('graph3', 'figure')],
[Input('intermediate-value', 'children')])
def update_graph(data):
#dff = pd.read_csv(data)
dff = pd.read_json(data) # or, more generally json.loads(jsonified_cleaned_data)
y = dff.groupby('Brand', as_index=False)['var_1'].mean().rename(columns={'var_1':'total'})
x = y['Brand']
table = dash_table.DataTable(
data=dff.to_dict('records'),
columns=[{'name': i, 'id': i} for i in dff.columns])
trace = go.Bar(x=x, y=y['total'])
layout = go.Layout(
#title='A good title goes here',
yaxis=dict(range=[0, 5],title='Avg Score'),
xaxis=dict(title='Brand'),
barmode='group',
bargap=0.15, # gap between bars of adjacent location coordinates.
bargroupgap=0.1 # gap between bars of the same location coordinate.
)
fig = go.Figure(data = [trace], layout=layout)
return table, fig
Layouts.py
import dash_core_components as dcc
import dash_html_components as html
layout1 = html.Div([
html.H3('App 1'),
html.Div(
[html.Div(id='table')]
),
html.Div(id='app-1-display-value'),
dcc.Link('Go to App 2', href='/app2')
])
layout2 = html.Div([
html.H3('App 2'),
html.Div(
[dcc.Graph(id='graph3')]
),
html.Div(id='app-2-display-value'),
dcc.Link('Go to App 1', href='/app1')
])