I have found what I’m pretty sure is a bug, since I can perform the exact action multiple times and get different results.
I have generated multiple tabs. The first Tab gets the data. The data is then stored in a hidden variable.
The second tab displays a launch button. When the button is pressed the titles of the numerical columns of the data frame that was uploaded should appear as a checklist. This however sometimes does not happen. Maybe every 1 in 5 times (sometimes 4 out of 5 times) fails to do anything and all buttons (apart from on Tab1) become unresponsive. No error message is given and repeatedly clicking launch gives “POST /_dash-update-component HTTP/1.1” 200 -"
Next if Tab 2 is launched but no Data is selected Tab 3 will become unresponsive. However if data in Tab 2 is then selected Tab 3 will immediately display the columns (signifying that the launch button on Tab 3 did properly record what happened)
I have used the code from https://dash.plot.ly/getting-started to generate the table in Tab 2.
If however the table in Tab 2 is removed:
Column data is generated correctly everytime and Tab 3 will generate Data when nothing is selected in Tab 2.
The code I’m using is as follows (apologies for the length):
import dash_html_components as html
import dash_core_components as dcc
import dash
import dash_table_experiments as dte
from dash.dependencies import Input, Output, State
import pandas as pd
import numpy as np
import json
import datetime
import operator
import os
import base64
import io
COLORS = [
{
},
]
def cell_style():
style = {
}
return style
def generate_table(dataframe):
rows = []
for i in range(len(dataframe)):
row = []
for col in dataframe.columns:
value = dataframe.iloc[i][col]
style = cell_style()
row.append(html.Td(value, style=style))
rows.append(html.Tr(row))
return html.Table(
# Header
[html.Tr([html.Th(col) for col in dataframe.columns])] +
# Body
rows)
def Sumation_Data(Data_Frame,Data_Name_List):
"""
Numberor can be set to the value in the dataframe you want to look at
"""
matrix_ad = [
["Name","Mean", "Standard deviation", "Sample size"],
]
return pd.DataFrame(matrix_ad,columns = matrix_ad.pop(0))
tab_style = {
}
selected_style = {
}
container_style = {
}
app = dash.Dash()
app.css.append_css({
"external_url": "https://codepen.io/chriddyp/pen/bWLwgP.css"
}),
TAB1 = [
html.Div(id='inter_df', style={'display': 'none'}),
html.Div([html.H5("Upload Files"),
dcc.Upload(
id='upload-data',
children=html.Div([
'Drag and Drop or ',
html.A('Select Files')
]),
style={
},
multiple=False),
html.Br(),
html.H5("Table"),
html.Div(dte.DataTable(rows=[{}], id='Table of Data')),]),
]
TAB2 = [
html.Div([
html.Button(
id='Make_Graph1',
n_clicks = 0,
children='Launch'
),
html.Div(html.H5("Column Data you want to Display")),
html.Div(
children =[
dcc.Checklist(
id = "Column_Names1",
values=[]
),
],
),
html.Hr(),
html.Div(id='Sumation_Data'),
]),
]
TAB3 = [
html.Div([
html.Button(
id='Make_Graph2',
n_clicks = 0,
children='Launch'
),
html.Div(html.H5("Column Data you want to Display")),
html.Div(
children =[
dcc.RadioItems(
id = "Column_Names2",
value=""
),
],
),
]),
]
app.scripts.config.serve_locally = True
app.config['suppress_callback_exceptions'] = True
app.layout = html.Div(
children = [
dcc.Tabs(
style=container_style,
value='tab-1',
vertical = False,
children=[
dcc.Tab(
children = TAB1,
label="Tab1",
value='tab-1',
style=tab_style,
selected_style=selected_style,
),
dcc.Tab(
children = TAB2,
label="Tab2",
value='tab-2',
style=tab_style,
selected_style=selected_style
),
dcc.Tab(
children = TAB3,
label="Tab3",
value='tab-3',
style=tab_style,
selected_style=selected_style
),
]
)
],
)
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:
return None
return df
# callback table creation
@app.callback(Output('Table of Data', '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.callback(
dash.dependencies.Output('Sumation_Data', 'children'),
[Input("inter_df","children"),
Input("Make_Graph1", "n_clicks"),
Input("Column_Names1","values")])
def Make_Histograms_Graph(af,Click,Column):
if Click < 1:
return []
else:
if Column == []:
return [{}]
else:
df = pd.read_json(af, orient='split')
if not df.empty:
a = Sumation_Data(df,Column)
return generate_table(a)
else:
return [{}]
#Columns========================================================================
@app.callback(
dash.dependencies.Output("Column_Names1", 'options'),
[Input("inter_df","children"),
Input("Make_Graph1", "n_clicks")])
def Make_Column_Options1_1(af,Click):
if Click < 1:
return []
else:
df = pd.read_json(af, orient='split')
if not df.empty:
return [{'label': i, 'value': i} for i in list(df.select_dtypes(['number']).columns.values)]
else:
return [{}]
@app.callback(
dash.dependencies.Output("Column_Names2", 'options'),
[Input("inter_df","children"),
Input("Make_Graph2", "n_clicks")])
def Make_Column_Options2(af,Click):
if Click < 1:
return []
else:
df = pd.read_json(af, orient='split')
if not df.empty:
return [{'label': i, 'value': i} for i in list(df.select_dtypes(['number']).columns.values)]
else:
return [{}]
@app.callback(
dash.dependencies.Output('inter_df', "children"),
[Input('Table of Data', 'rows')])
def Transform_Data(Data):
inter = pd.DataFrame.from_dict(Data)
return inter.to_json(date_format='iso', orient='split')
app.scripts.config.serve_locally = True
if __name__ == '__main__':
app.run_server(debug=True)
Many thanks