Hello everyone, I am trying to make a simple app with two tabs. The first tab is made of 2 dropdown to select the data of interest, while the second tab is used to display the data. I use a dcc.Store()
component to store the full data, a dictionary where the key is the name of a given dataset, and the value is a pandas dataframe.
The first tab allows the user to select a dataframe and a variable of interest (one column of the dataframe).
I created a callback to store the selected value to display in a hidden Div. The callback takes 3 Inputs, the values of the two dropdown and the data from the Store component.
For simplicity I created a simple callback that displays a dummy result on the second tab instead of displaying the data in a graph.
The problem is that I get an error: A nonexistent object was used in an Input
of a Dash callback. The id of this object is dataset-dropdown
and the property is value
. The string ids in the current layout are: [json-data, tabs-example, tabs-content-example, active-dataframe].
If I only use the two dropdown values as Input for the callback (which is useless because that way I cannot get any data), I do not get the error.
The file structure is as follows:
main.py
tabs folder
— tab_1.py
— tab_2.py
Main.py
import dash
from dash.dependencies import Input, Output
import dash_html_components as html
import dash_core_components as dcc
from tabs import tab_1
from tabs import tab_2
import json
import pandas as pd
import random
app = dash.Dash(
__name__,
meta_tags=[{"name": "viewport", "content": "width=device-width, initial-scale=1"}],
)
app.config['suppress_callback_exceptions'] = True
# Creating dataframes
df1 = pd.DataFrame({
'timestep':list(range(10)),
'Var1':[round(random.uniform(0,100),2) for i in range(10)],
'Var2':[round(random.uniform(0,100),2) for i in range(10)],
'Var3':[round(random.uniform(0,100),2) for i in range(10)]
})
df2 = pd.DataFrame({
'timestep':list(range(10)),
'Var1':[round(random.uniform(0,100),2) for i in range(10)],
'Var2':[round(random.uniform(0,100),2) for i in range(10)],
'Var3':[round(random.uniform(0,100),2) for i in range(10)]
})
df3 = pd.DataFrame({
'timestep':list(range(10)),
'Var1':[round(random.uniform(0,100),2) for i in range(10)],
'Var2':[round(random.uniform(0,100),2) for i in range(10)],
'Var3':[round(random.uniform(0,100),2) for i in range(10)]
})
data_dict = {'df1':df1, 'df2':df2, 'df3':df3}
# converting all df to json format
for key, value in data_dict.items():
data_dict[key] = data_dict[key].to_json(date_format=None, orient='index')
serialized_data = json.dumps(data_dict)
app.layout = html.Div([
dcc.Store(id='json-data', data=serialized_data),
html.H1('Dash Tabs component demo'),
dcc.Tabs(id="tabs-example", value='tab-1-example', children=[
dcc.Tab(label='Tab One', value='tab-1-example'),
dcc.Tab(label='Tab Two', value='tab-2-example'),
]),
html.Div(id='tabs-content-example'),
html.Div(id='active-dataframe', style={'display':'none'}),
])
@app.callback(Output('tabs-content-example', 'children'),
[Input('tabs-example', 'value')])
def render_content(tab):
if tab == 'tab-1-example':
return tab_1.tab_1_layout
elif tab == 'tab-2-example':
return tab_2.tab_2_layout
# Tab 1 callback
@app.callback(Output('active-dataframe', 'children'),
[
Input('json-data', 'data'),
Input('dataset-dropdown', 'value'),
Input('variable-dropdown', 'value')
])
def get_dataframe(json_data, selected_dataset, selected_variable):
return("selected df: {} selected variable: {}".format(selected_dataset, selected_variable))
# Tab 2 callback
@app.callback(Output('page-2-content', 'children'),
[Input('active-dataframe', 'children')])
def page_2_radios(value):
return value
if __name__ == '__main__':
app.run_server(debug=True)
tab_1.py
import dash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output
import json
list_of_dataset = ['df1', 'df2', 'df3']
list_of_variables = ['Var1', 'Var2', 'Var3']
tab_1_layout = html.Div([
# Manually select metrics
html.Div(
id="set-specs-intro-container",
# className='twelve columns',
children=html.P(
children="Pick a dataset and a variable",
style={'textAlign':'center'}
),
),
html.Div(
id="settings-menu",
children=[
html.Div(
id="dataset-select-menu",
# className='five columns',
children=[
html.Label(id="dataset-select-title", children="Pick a dataset"),
html.Br(),
dcc.Dropdown(
id="dataset-dropdown",
options=list(
{"label": dataset, "value": dataset} for dataset in list_of_dataset
),
value=list_of_dataset[0],
),
],
style={'width': '48%', 'display': 'inline-block'}
),
html.Div(
id="variable-select-menu",
# className='five columns',
children=[
html.Label(
id="variable-select-title",
children="Pick a variable",
style={'width': '48%', 'float':'right', 'display': 'inline-block'}
),
html.Br(),
dcc.Dropdown(
id="variable-dropdown",
options=list(
{"label": variable, "value": variable} for variable in list_of_variables
),
value=list_of_variables[0],
),
],
style={'width': '48%', 'float':'right', 'display': 'inline-block'}
)
],
)
],
)
tab_2
import dash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output
tab_2_layout = html.Div([
html.H1('Page 2'),
html.Div(id='page-2-content')
])
I hope it makes sense. Thanks for your help!