Dash python tab && px.bar

Hello everyone,
When I am programming, I met some errors and I d’ont known why, but it seems that it works?

Question 1:
After refreshing and without any clicks, there are the errors “ID not found in layout”


I thought that there are something wrong because of the tab?

Question 2:
After clicking le tab “onglet1”, there is an error “callback updating”

Question 3:
What I wanna to do is that it will output more images (it could be one or several figures) if I choose one more option. What I use is px.bar, so I would like to ask if I could set the height of each figure? And, can each figure prints the details of xaxe?
Or, can I seperate the figures?

Thx a lot!

Hi,

Could you please make sure to submit your questions with code, just to encourage other users to answer quicker? The pictures are very helpful, but in many cases not enough to tell what exactly is wrong with your code…

That said, I will give you some tips of what is probably the issue in each of the questions below:

Question 1: You are probably updating the tab content via a callback (method 1 here) and the Ids raised in the errors are part of the content of each tab. This can be fixed by adding a validation layout with the missing ids, as explained in this link: Multi-Page Apps and URL Support | Dash for Python Documentation | Plotly

Question 2: opt_org is None, therefore the error. You can whether write an if-statement to deal with this case specifically or (maybe) try to write the dcc.Dropdown with a default value=[].

Question 3: I will need some clarification about which options are you talking about and what you mean by “details of xaxis”? But yes, you can set the size of each figure in the layout and you can generate multiple figures at once in a callback.

2 Likes
from dash import Dash, dcc, html, dash_table, State, MATCH, ALL
from dash.dependencies import Input, Output
import os
import chardet #encoding
import requests
import dash_bootstrap_components as dbc
import numpy as np
import pandas as pd
import plotly.express as px
import plotly.graph_objects as go
import matplotlib
import matplotlib.pyplot as plt

#################### tester.csv ####################

headers_sans_accents = ['dateDebut','dateFin','organisme','codeZas','zas','codeSite/modele','nomSite/modele','typeImplantation','polluant','typeInfluence','discriminant','reglementaire','typeEvaluation','procedureMesure/modelisation','typeValeur','valeur','valeurBrute','uniteMesure','tauxSaisie','couvertureTemporelle','couvertureDonnees','codeQualite','validite']
df = pd.read_csv("tester.csv",sep=';', header = 1, index_col = False, names = headers_sans_accents)
df['reseau'] = df['codeSite/modele'].apply(lambda x:x[2:4])
df['heure'] = pd.to_datetime(df['dateDebut']).dt.hour
df['jour'] = pd.to_datetime(df['dateDebut']).dt.month
df['mesure'] = df['codeSite/modele'] + '_' + df['polluant'] + '_' + df['discriminant']
df_donnees_valides = df[['heure','organisme','reseau','jour','mesure','typeValeur','validite']]
validees_nb_mesures = df.groupby(['reseau','jour','heure','organisme','typeValeur']).count().reset_index()
tab_validees_nb_mesures = validees_nb_mesures[validees_nb_mesures['heure']==0][['reseau','jour','zas','organisme','typeValeur']]
tab_validees_nb_mesures.columns = ['reseau','jour','nbr','organisme','typeValeur']

#################### référentiel_organisme.csv ## df_ref_org ####################

with open('référentiel_organisme.csv', 'rb') as f:
    enc = chardet.detect(f.read())  # or readline if the file is large
    df_ref_org = pd.read_csv('référentiel_organisme.csv', sep=';', index_col = False, encoding = enc['encoding'])
    org_ord = df_ref_org[['organisme','ordre']].drop_duplicates().reset_index(drop=True)
    keys=org_ord['organisme']
    values=org_ord['ordre']
    dict_org_ord=dict(zip(keys, values))

#################### testerQH.csv ####################

df_QH = pd.read_csv("testerQH.csv",sep=';', header = 1, index_col = False, names = headers_sans_accents)
df_QH['reseau'] = df_QH['codeSite/modele'].apply(lambda x:x[2:4])
df_QH_counts = df_QH.groupby(['organisme','typeValeur','reseau'])['dateDebut'].value_counts().reset_index(name='counts')

############################################################


Onglet1 = html.Div([
    html.H3('Tab content 1'),
    html.Br(),
    html.Div([
        html.Div([
            dbc.Label("Organismes"),
            dcc.Dropdown(options=df_ref_org['organisme'].unique(), placeholder="Sélectionnez des organismes", id='org', multi=True)
        ],style={"width":"50%"}),
        html.Div([
            dbc.Label("Polluants"),
            dcc.Dropdown(['a', 'b'], 'a', placeholder="Sélectionnez des polluants", multi=True)
        ],style={"width":"50%"}),
    ],style={"display":"flex"}),
    html.Br(),
    html.Button(id='btn-rafraichir',children='Rafraichir'),
    html.Br(),
    html.Div([
        html.Div([
            dcc.Graph(id='graph-hist-org')
        ],style={"width":"50%"}),
        html.Div([
            dcc.Graph(id='graph-line-org')
        ],style={"width":"50%"}),
     ],style={"display":"flex"}),
])
    
    
Onglet2 = html.Div([
    html.H3('Tab content 2'),
    dcc.Graph(id='graph-2-tabs',)
])

app = Dash(__name__)
app_tabs = html.Div([
    dcc.Tabs(id="tabs", value='tab-1-graph',children=[
        dcc.Tab(label='Onglet 1', value='tab-1'),
        dcc.Tab(label='Onglet 2', value='tab-2'),
        dcc.Tab(label='Onglet 3', value='tab-3'),
        dcc.Tab(label='Onglet 4', value='tab-4'),
    ],
        
    ),
])
app.layout = dbc.Container([
    dbc.Row(dbc.Col(html.H1("Demo  18févr.2022"))),
    html.Br(),
    dbc.Row(dbc.Col(app_tabs, width=12)),
    html.Div(id='tabs-content', children=[])

])

@app.callback(Output('tabs-content', 'children'),
              Input('tabs', 'value'))
def render_content(tab):
    if tab == 'tab-1':
        return Onglet1
    elif tab == 'tab-2':
        return Onglet2

    
    

    
    
@app.callback(
    Output(component_id='graph-hist-org', component_property='figure'),
    Input(component_id='org', component_property='value')
)
def update_hist_org(opt_org):
    df_hist = tab_validees_nb_mesures[tab_validees_nb_mesures['organisme'].isin(opt_org)]
    fig_hist = px.bar(df_hist, x="jour", y="nbr", color="typeValeur", facet_col="reseau",facet_row_spacing=0.05,facet_col_wrap=1, height=500, labels={'typeValeur':'type de valeur'})
    return fig_hist
        
        
@app.callback(
    Output(component_id='graph-line-org', component_property='figure'),
    Input(component_id='org', component_property='value')
)
def update_line_org(opt_org):
    df_QH_fig = df_QH_counts[df_QH_counts['organisme'].isin(opt_org)]
    fig_line = px.scatter(df_QH_fig, x='dateDebut', y='counts', color='typeValeur', symbol="typeValeur",facet_col="reseau",facet_col_wrap=1, height=500)
    return fig_line


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

Hi thank you for your answer. I have read the links given, so I change some codes and divided it into 3 parts(app.py, onglet1.py and onglet2.py) .
But it still exists the errors.

And I wanna to ask more about the mutiple figures. The model that I imagine is as follows:


Thus, I want to make sure that each figure has the same size ( If I set the height of px.bar, it will be divided into the several figures, and when I change the numbers of the selections, it will be bizarre. which is bad for me).

Thanks a lot again for all your answers!

I paste the codes here, shall I upload the databases?

##########app.py
from dash import Dash, dcc, html, callback, dash_table, State, MATCH, ALL
from dash.dependencies import Input, Output
import os
import chardet #encoding
import requests
import dash_bootstrap_components as dbc
import numpy as np
import pandas as pd
import plotly.express as px
import plotly.graph_objects as go
import matplotlib
import matplotlib.pyplot as plt

from onglet1 import onglet1_layout
from onglet2 import onglet2_layout


app = Dash(__name__)
app_tabs = html.Div([
    dcc.Tabs(id="tabs", value='tab-1',children=[
        dcc.Tab(label='Onglet 1', value='tab-1'),
        dcc.Tab(label='Onglet 2', value='tab-2'),
        dcc.Tab(label='Onglet 3', value='tab-3'),
        dcc.Tab(label='Onglet 4', value='tab-4'),
    ]),
])

#app.layout = html.Div([
#    html.H1("Demo  18févr.2022"),
#    dcc.Location(id='url', refresh=False),
#    html.Div(id='page-content')
#])
app.layout = dbc.Container([
    dbc.Row(dbc.Col(html.H1("Demo  18févr.2022"))),
    html.Br(),
    dbc.Row(dbc.Col(app_tabs, width=12)),
    html.Div(id='tabs-content', children=[])
])


@callback(Output('tabs-content', 'children'),           #######error?
              Input('tabs', 'value'))
def render_content(tab):
    if tab == 'tab-1':
        return onglet1_layout
    elif tab == 'tab-2':
        return onglet2_layout



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


######### onglet1.py
from dash import Dash, dcc, html, callback, dash_table, State, MATCH, ALL
from dash.dependencies import Input, Output
import os
import chardet #encoding
import requests
import dash_bootstrap_components as dbc
import numpy as np
import pandas as pd
import plotly.express as px
import plotly.graph_objects as go
import matplotlib
import matplotlib.pyplot as plt

#################### référentiel_organisme.csv ## df_ref_org ####################

with open('référentiel_organisme.csv', 'rb') as f:
    enc = chardet.detect(f.read())  # or readline if the file is large
    df_ref_org = pd.read_csv('référentiel_organisme.csv', sep=';', index_col = False, encoding = enc['encoding'])
    org_ord = df_ref_org[['organisme','ordre']].drop_duplicates().reset_index(drop=True)
    keys=org_ord['organisme']
    values=org_ord['ordre']
    dict_org_ord=dict(zip(keys, values))

#################### tester.csv ####################
headers_sans_accents = ['dateDebut','dateFin','organisme','codeZas','zas','codeSite/modele','nomSite/modele','typeImplantation','polluant','typeInfluence','discriminant','reglementaire','typeEvaluation','procedureMesure/modelisation','typeValeur','valeur','valeurBrute','uniteMesure','tauxSaisie','couvertureTemporelle','couvertureDonnees','codeQualite','validite']
df = pd.read_csv("tester.csv",sep=';', header = 1, index_col = False, names = headers_sans_accents)
df['heure'] = pd.to_datetime(df['dateDebut']).dt.hour
df['jour'] = pd.to_datetime(df['dateDebut']).dt.month
df['reseau'] = df['codeSite/modele'].apply(lambda x:x[2:4])
df['mesure'] = df['codeSite/modele'] + '_' + df['polluant'] + '_' + df['discriminant']
df_donnees_valides = df[['heure','organisme','reseau','jour','mesure','typeValeur','validite']]
validees_nb_mesures = df.groupby(['reseau','jour','heure','organisme','typeValeur']).count().reset_index()
tab_validees_nb_mesures = validees_nb_mesures[validees_nb_mesures['heure']==0][['reseau','jour','zas','organisme','typeValeur']]
tab_validees_nb_mesures.columns = ['reseau','jour','nbr','organisme','typeValeur']
tab_validees_nb_mesures['ordre'] = tab_validees_nb_mesures['organisme'].apply(lambda x : dict_org_ord[x])
tab_validees_nb_mesures = tab_validees_nb_mesures.sort_values(by=['ordre','reseau','jour'])
tab_validees_nb_mesures['label'] = tab_validees_nb_mesures['organisme'] + "       réseau=" + tab_validees_nb_mesures['reseau']


#################### testerQH.csv ####################

df_QH = pd.read_csv("testerQH.csv",sep=';', header = 1, index_col = False, names = headers_sans_accents)
df_QH['reseau'] = df_QH['codeSite/modele'].apply(lambda x:x[2:4])
df_QH_counts = df_QH.groupby(['organisme','typeValeur','reseau'])['dateDebut'].value_counts().reset_index(name='counts')
df_QH_counts['ordre'] = df_QH_counts['organisme'].apply(lambda x : dict_org_ord[x])
df_QH_counts = df_QH_counts.sort_values(by=['ordre','reseau','dateDebut'])
df_QH_counts['label'] = df_QH_counts['organisme'] + "       réseau=" + df_QH_counts['reseau']

############################################################


onglet1_layout = html.Div([
    html.H3('Tab content 1'),
    html.Br(),
    html.Div([
        html.Div([
            dbc.Label("Organismes"),
            dcc.Dropdown(options=df_ref_org['organisme'].unique(), placeholder="Sélectionnez des organismes", id='org', multi=True)
        ],style={"width":"50%"}),
        html.Div([
            dbc.Label("Polluants"),
            dcc.Dropdown(['a', 'b'], 'a', placeholder="Sélectionnez des polluants", multi=True)
        ],style={"width":"50%"}),
    ],style={"display":"flex"}),
    html.Br(),
    html.Button(id='btn-rafraichir',children='Rafraichir'),
    html.Br(),
    html.Div([
        html.Div([
            dcc.Graph(id='graph-hist-org')
        ],style={"width":"50%"}),
        html.Div([
            dcc.Graph(id='graph-line-org')
        ],style={"width":"50%"}),
    ],style={"display":"flex"}),
])
    
    
@callback(
    Output(component_id='graph-hist-org', component_property='figure'),
    Input(component_id='org', component_property='value')
)
def update_hist_org(opt_org):
    #opt_org=["ATMO SUD","ATMO REUNION","ATMO GRAND EST"]
    df_hist = tab_validees_nb_mesures[tab_validees_nb_mesures['organisme'].isin(opt_org)]
    fig_hist = px.bar(df_hist, x="jour", y="nbr", color="typeValeur", facet_col="reseau", facet_row_spacing=0.05,facet_col_wrap=1,labels={'typeValeur':'typeValeur', 'reseau':'réseau', 'label':'organisme'}) # animation_frame 
    return fig_hist
        
        
@callback(
    Output(component_id='graph-line-org', component_property='figure'),
    Input(component_id='org', component_property='value')
)
def update_line_org(opt_org):
    df_QH_fig = df_QH_counts[df_QH_counts['organisme'].isin(opt_org)]
    fig_line = px.scatter(df_QH_fig, x='dateDebut', y='counts', color='typeValeur', symbol="typeValeur",facet_col="label",facet_col_wrap=1,labels={'typeValeur':'type de valeur', 'reseau':'réseau', 'label':'organisme', 'dateDebut':'date de début'})
    return fig_line


######### onglet2.py
from dash import Dash, dcc, html, callback, dash_table, State, MATCH, ALL
from dash.dependencies import Input, Output
import os
import chardet #encoding
import requests
import dash_bootstrap_components as dbc
import numpy as np
import pandas as pd
import plotly.express as px
import plotly.graph_objects as go
import matplotlib
import matplotlib.pyplot as plt


onglet2_layout =  html.Div([
    html.H3('Tab content 2'),
    dcc.Graph(id='graph-2-tabs',)
])

THANK YOU!!!

Hi @SUN
can you please put your code in preformatted text </>. I showed you an example with the first part of your code. That would make reading your question a lot easier.

Thank you,

Thank you for your reminding, I’ve changed the style of the codes.

1 Like

As I mentioned in my first answer, the problem of missing IDs in this situation is because some of the components in the callbacks input might be missing in the app lifetime (depending on which tab is selected).

You can whether follow the error instructions of adding suppress_callback_exceptions=True to the app, or add a validation layout. In your case, the validation layout can be defined like:


index_layout = dbc.Container([
    dbc.Row(dbc.Col(html.H1("Demo  18févr.2022"))),
    html.Br(),
    dbc.Row(dbc.Col(app_tabs, width=12)),
    html.Div(id='tabs-content', children=[])
])

# Format doesn't matter, this is just to check if IDs exist in layout
app.validation_layout = html.Div(
   [
        index_layout,
        onglet1_layout,
        onglet2_layout
   ]
)

app.layout = index_layout

Thank you very much!!