I keep receiving callback error. I would like to know what's wrong here. Could you guys help?

So, here is the full code:

from dash import Dash, html, dcc, Input, Output, State
import dash_bootstrap_components as dbc
import plotly.express as px
import pandas as pd
import numpy as np

#================================================#

app = Dash(__name__, external_stylesheets= [dbc.themes.LUX])

df = pd.read_csv('df.csv')
df_fun = pd.read_csv('df_fun.csv')

#================================================#

fig = px.histogram(
            df,
            y= 'Categoria',
            color= 'GĂȘnero',
            template= 'plotly_white',
            barmode= 'group',
            title= '<b>FORÇA DE TRABALHO POR GÊNERO</b>',
            category_orders= {
                'Categoria': [
                    'Membra/Membro',
                    'Analista',
                    'TĂ©cnica/TĂ©cnico',
                    'Pessoal sem vĂ­nculo',
                    'Requisitada/Requisitado',
                    'EstagiĂĄria/EstagiĂĄrio'
                ],
                'GĂȘnero': ['Mulheres', 'Homens']
            },
            hover_data= {
                'GĂȘnero': False,
                'Categoria': False
            } 
        )

fig.update_layout(
            font_family= 'Bahnschrift',
            font_size= 13,
            xaxis_title= '',
            yaxis_title= '',
            height= 450,
            width= 900,
            legend_title= '',
            legend_x= 1,
            legend_y= 1.25,
            legend_xanchor= 'right',
            xaxis_dtick= 100,
            hoverlabel_font_color= 'white' 
        )

fig.update_traces(
            marker_line_width= 0.3,
            marker_line_color= 'black',
            hovertemplate= (
                'Total: %{x} <extra></extra>'
            )
        )

#================================================#

SIDEBAR_STYLE = {
    "position": "fixed",
    "top": 0,
    "left": 0,
    "bottom": 0,
    "width": "13rem",
    "padding": "2rem 1rem",
    "background-color": "lightgray",
    'color': 'black'
}

RIGHT_INFO_STYLE = {
    "margin-left": "6rem",
    "margin-right": "1rem",
    "padding": "2rem 1rem"
}

sidebar = html.Div(
    [
        html.H2("MPT", className="display-4", style= {'text-align':'center', 'color':'red'}),
        html.H3('Dashboard', style= {'text-align':'center', 'color':'brown'}),
        html.Hr(),
        html.P("Selecione abaixo as informaçÔes de interesse:", className="lead"),
        html.P('Composição', style= {'font-weight':'bold', 'text-decoration': 'underline'}),
        dcc.RadioItems(options=[
            {'label':'Força de Trabalho Total', 'value':'FT'},
            {'label':'Membras/Membros', 'value':'MM'},
            {'label':'Servidores', 'value':'S'}], value= 'FT', id= 'comp'),
        html.Hr(),
        html.P('Gratificação', style= {'font-weight':'bold', 'text-decoration': 'underline'}),
        dcc.RadioItems(options=[
            {'label':'Indiferente', 'value':'Ind'},
            {'label':'Com Função', 'value':'CF'},
            {'label':'Sem Função', 'value':'SF'}], value= 'Ind', id= 'grat'),
        html.Hr(),
        html.P('Informação', style= {'font-weight':'bold', 'text-decoration': 'underline'}),
        dcc.Checklist(options= ['GĂȘnero', 'Cor/Raça', 'Faixa de Idade', 'DeficiĂȘncia'], value= ['GĂȘnero'], id= 'info'),
        html.Br(),
        dbc.Button('Gerar', id= 'button', n_clicks= 0)
    ],
    style= SIDEBAR_STYLE
)

app.layout = dbc.Container([sidebar, 
                            html.Div(dcc.Graph(id= 'graph', figure= fig), style= RIGHT_INFO_STYLE)])

#================================================#
@app.callback(
    Output('graph', 'figure'),
    State('comp', 'value'),
    State('grat', 'value'),
    State('info', 'value'),
    Input('button', 'n_clicks')
)
def FT_gĂȘnero(comp_value, grat_value, info_value):
    if grat_value == 'Indiferente' and info_value == 'GĂȘnero' and comp_value == 'Força de Trabalho Total':
        fig = px.histogram(
            df,
            y= 'Categoria',
            color= 'GĂȘnero',
            template= 'plotly_white',
            barmode= 'group',
            title= '<b>FORÇA DE TRABALHO POR GÊNERO</b>',
            category_orders= {
                'Categoria': [
                    'Membra/Membro',
                    'Analista',
                    'TĂ©cnica/TĂ©cnico',
                    'Pessoal sem vĂ­nculo',
                    'Requisitada/Requisitado',
                    'EstagiĂĄria/EstagiĂĄrio'
                ],
                'GĂȘnero': ['Mulheres', 'Homens']
            },
            hover_data= {
                'GĂȘnero': False,
                'Categoria': False
            } 
        )

        fig.update_layout(
            font_family= 'Bahnschrift',
            font_size= 13,
            xaxis_title= '',
            yaxis_title= '',
            height= 450,
            width= 900,
            legend_title= '',
            legend_x= 1,
            legend_y= 1.25,
            legend_xanchor= 'right',
            xaxis_dtick= 100,
            hoverlabel_font_color= 'white' 
        )

        fig.update_traces(
            marker_line_width= 0.3,
            marker_line_color= 'black',
            hovertemplate= (
                'Total: %{x} <extra></extra>'
            )
        )

    elif grat_value == 'Com Função' and info_value == 'GĂȘnero' and comp_value == 'Força de Trabalho Total':
        df = pd.DataFrame(
            df.loc[df['Identificado de Gratificacao'] == 'Com Função', :].groupby(
            ['Identificado de Gratificacao', 'GĂȘnero'])['GĂȘnero'].count().reset_index(name= 'Total')
        )
        fig = px.pie(
            df,
            values= 'Total',
            names= 'GĂȘnero',
            template= 'plotly_white',
            title= '<b>FORÇA DE TRABALHO COM FUNÇÃO, POR GÊNERO</b>',
            category_orders= {'GĂȘnero': ['Mulheres', 'Homens']},
            hover_data= {'GĂȘnero': False} 
        )

        fig.update_layout(
            font_family= 'Bahnschrift',
            font_size= 13,
            height= 650,
            width= 900,
            legend_x= 1.18,
            legend_y= 0.8,
            legend_xanchor= 'right',
            hoverlabel_font_color = 'white'
        )

        fig.update_traces(
            pull= 0.04,
            textfont_color= 'white'
        )
    else:
        df = pd.DataFrame(
            df.loc[df['Identificado de Gratificacao'] == 'Sem Função', :].groupby(
            ['Identificado de Gratificacao', 'GĂȘnero'])['GĂȘnero'].count().reset_index(name= 'Total')
        )
        fig = px.pie(
            df,
            values= 'Total',
            names= 'GĂȘnero',
            template= 'plotly_white',
            title= '<b>FORÇA DE TRABALHO SEM FUNÇÃO, POR GÊNERO</b>',
            category_orders= {'GĂȘnero': ['Mulheres', 'Homens']},
            hover_data= {'GĂȘnero': False} 
        )

        fig.update_layout(
            font_family= 'Bahnschrift',
            font_size= 13,
            height= 650,
            width= 900,
            legend_x= 1.18,
            legend_y= 0.8,
            legend_xanchor= 'right',
            hoverlabel_font_color = 'white'
        )

        fig.update_traces(
            pull= 0.04,
            textfont_color= 'white'
        )
    return fig

#=================================================#

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

What might be wrong there? The callback error keeps appearing


It’s hard to know for sure because there is no sample data and I can’t run your app, but it’s likely that you are missing a variable in the callback function. There are 4 inputs - 3 States for the RadioItems and Checklist, and 1 Input for the Button, but only 3 variables

app.callback(
    Output('graph', 'figure'),
    State('comp', 'value'),
    State('grat', 'value'),
    State('info', 'value'),
    Input('button', 'n_clicks')
)
def FT_gĂȘnero(comp_value, grat_value, info_value):


Try changing the function to:

def FT_gĂȘnero(comp_value, grat_value, info_value, n):

If that doesn’t fix the issue, please share the error message and some sample data :slight_smile:

1 Like

Hi, thanks for your help. I’ve check that and actually I did put another parameter into the function. I posted here the old version of the code. Here it is how the function is actually structured:

@app.callback(
    Output('graph', 'figure'),
    Input('button', 'n_clicks'),
    State('comp', 'value'),
    State('grat', 'value'),
    State('info', 'value')   
)
def FT_gĂȘnero(n_clicks, comp_value, grat_value, info_value):
    global df
    if grat_value == 'Indiferente' and info_value == 'gen' and comp_value == 'Força de Trabalho Total':
        fig = px.histogram(
            df,
            y= 'Categoria',
            color= 'GĂȘnero',
            template= 'plotly_white',
            barmode= 'group',
            title= '<b>FORÇA DE TRABALHO POR GÊNERO</b>',
            category_orders= {
                'Categoria': [
                    'Membra/Membro',
                    'Analista',
                    'TĂ©cnica/TĂ©cnico',
                    'Pessoal sem vĂ­nculo',
                    'Requisitada/Requisitado',
                    'EstagiĂĄria/EstagiĂĄrio'
                ],
                'GĂȘnero': ['Mulheres', 'Homens']
            },
            hover_data= {
                'GĂȘnero': False,
                'Categoria': False
            } 
        )

        fig.update_layout(
            font_family= 'Bahnschrift',
            font_size= 13,
            xaxis_title= '',
            yaxis_title= '',
            height= 450,
            width= 900,
            legend_title= '',
            legend_x= 1,
            legend_y= 1.25,
            legend_xanchor= 'right',
            xaxis_dtick= 100,
            hoverlabel_font_color= 'white' 
        )

        fig.update_traces(
            marker_line_width= 0.3,
            marker_line_color= 'black',
            hovertemplate= (
                'Total: %{x} <extra></extra>'
            )
        )

    elif grat_value == 'Com Função' and info_value == 'GĂȘnero' and comp_value == 'Força de Trabalho Total':
        df = pd.DataFrame(
            df.loc[df['Identificado de Gratificacao'] == 'Com Função', :].groupby(
            ['Identificado de Gratificacao', 'GĂȘnero'])['GĂȘnero'].count().reset_index(name= 'Total')
        )
        fig = px.pie(
            df,
            values= 'Total',
            names= 'GĂȘnero',
            template= 'plotly_white',
            title= '<b>FORÇA DE TRABALHO COM FUNÇÃO, POR GÊNERO</b>',
            category_orders= {'GĂȘnero': ['Mulheres', 'Homens']},
            hover_data= {'GĂȘnero': False} 
        )

        fig.update_layout(
            font_family= 'Bahnschrift',
            font_size= 13,
            height= 650,
            width= 900,
            legend_x= 1.18,
            legend_y= 0.8,
            legend_xanchor= 'right',
            hoverlabel_font_color = 'white'
        )

        fig.update_traces(
            pull= 0.04,
            textfont_color= 'white'
        )
    else:
        df = pd.DataFrame(
            df.loc[df['Identificado de Gratificacao'] == 'Sem Função', :].groupby(
            ['Identificado de Gratificacao', 'GĂȘnero'])['GĂȘnero'].count().reset_index(name= 'Total')
        )
        fig = px.pie(
            df,
            values= 'Total',
            names= 'GĂȘnero',
            template= 'plotly_white',
            title= '<b>FORÇA DE TRABALHO SEM FUNÇÃO, POR GÊNERO</b>',
            category_orders= {'GĂȘnero': ['Mulheres', 'Homens']},
            hover_data= {'GĂȘnero': False} 
        )

        fig.update_layout(
            font_family= 'Bahnschrift',
            font_size= 13,
            height= 650,
            width= 900,
            legend_x= 1.18,
            legend_y= 0.8,
            legend_xanchor= 'right',
            hoverlabel_font_color = 'white'
        )

        fig.update_traces(
            pull= 0.04,
            textfont_color= 'white'
        )
    return fig

And the problem persists. I’ll share more information:

As matter of fact I’m not receiving callback error anymore. The figure that starts the page are the last figure inside the function (the plot called “FORÇA DE TRABALHO SEM FUNÇÃO, POR GÊNERO”) however the radioitems and checklist doesn’t match the figure. They start correctly accordingnaly to its values set in app.layout(sidebar) but the corresponding plot are not correct. When I try to change te RadioItems and Checklist nothing happens with the figure. Everything remains the same. Here it is:

On the image bellow is the df.head(). The DataFrame I’m using.

Hi @rlarango

Please see Why Global Variables Will Break Your App

Yeah! I saw an hour ago that It’s not a good habit keeping global variables inside functions. I managed to make a copy. However, I’ve finally found the reason things weren’t working out! The parameter inside the function regarding the Checklist was being passed into the condition as a simple string, although it should be inside brackets because this dcc’s value is fulfilled with a list of strings after all! Thank you for your help!