Search code examples
pythoncallbackplotlyplotly-dash

input text in plotly dash based on a RadioItem picker


I have a code where i use plotly dash radio item to pick from different tests ('weekness', 'std', etc.) The main code is shown below.

def plots(self,):    
        
        df_lists = self.df_lists
        plots_names = ['weakness', 'std', 'std_average', 'std_weak', 'p_mean', 'p_mean_average', 'p_median', 'p_median_average','range', 'p_range_average']
        colors = {'background': '#111111', 'text': '#7FDBFF'}
        from dash import Dash, dcc, html, Input, Output
        names = self.names
        app = Dash()
        app.layout = html.Div( children=[
            html.H4('Dieharder Tests Plots'),
            dcc.Graph(id="bar-plot",  style={'width':'80%', 'height': '70vh','display':'inline-block'}),
            html.Div([  # this Div contains our output graph
            dcc.Graph(id='side-plot', )], style={'width':'20%', 'height':'70vh','display':'inline-block'}),
            html.P('Test Description'),
            dcc.Markdown(id='test-explain',  link_target="_blank", ),
            html.P('Chose Plot Type'),
            dcc.RadioItems(plots_names, plots_names[0], id="plot-picker", ),
            html.P("Filter by test:"),
            dcc.Dropdown(names, names[0], id="test-picker", multi = True), 
           
                ]) 

Now, i want to display an explanation to the tests whenever one is picked using the radio item button. I am using the following @app.callback code: (note i am just displaying one text for the 'weakness' test)

@app.callback(
        Output('est-explain', 'children'), [Input("test-picker", "value")])
        def update_chart_info(picker_test):
            if picker_test == 'weakness':
                text = "This test counts how many weak results are there for each test for all rounds and return the number divided by the number of rounds"
            return [text]  

however, i am not getting anything on the dashboard when i run the code. I mean, the code works for other callbacks (that are not shown here) however it is not working for the callback for displaying the text. I tried different dcc components, such as html and markdown, but still can't see the explanation displayed. any suggestions?

Thanks


Solution

  • There's a few issues that are probably preventing your callback from working as intended:

    • you have a typo in your callback arguments and Output('est-explain', 'children') should be Output('test-explain', 'children')
    • you mentioned you want the Dash app to update based on the selection from the Radioitem component, but Input("test-picker", "value") refers to the id for your Dropdown component, so you probably want to change it to Input("plot-picker", "value")
    • you'll also need a condition in your callback for when the Radioitem selection isn't "weakness" – otherwise you'll get something like UnboundLocalError: local variable 'text' referenced before assignment whenever someone selects another radioitem because update_chart_info won't know what text is supposed to be (for simplicity, I am returning an empty string whenever anything option besides "weakness" is selected, but you can modify this as needed)

    The following should work:

    @app.callback(
        Output('test-explain', 'children'), 
        Input('plot-picker', 'value')
    )
    def update_chart_info(radio_selection):
        if radio_selection == 'weakness':
            text = "This test counts how many weak results are there for each test for all rounds and return the number divided by the number of rounds"
        else:
            text = ""
        return [text]
    

    And here is a small working example:

    import plotly.graph_objects as go
    from dash import Dash, dcc, html, Input, Output
    
    plots_names = ['weakness', 'std', 'std_average', 'std_weak', 'p_mean', 'p_mean_average', 'p_median', 'p_median_average','range', 'p_range_average']
    colors = {'background': '#111111', 'text': '#7FDBFF'}
    
    ## sample names
    names = ['weakness','other']
    
    app = Dash(__name__)
    app.layout = html.Div(
        [
            html.H4('Dieharder Tests Plots'),
            dcc.Graph(id="bar-plot",  style={'width':'80%', 'height': '70vh','display':'inline-block'}),
            html.Div([
                  # this Div contains our output graph
                dcc.Graph(id='side-plot', )
            ], style={'width':'20%', 'height':'70vh','display':'inline-block'}),
            html.P('Test Description'),
            dcc.Markdown(id='test-explain',  link_target="_blank", ),
            html.P('Chose Plot Type'),
            dcc.RadioItems(plots_names, plots_names[0], id="plot-picker", ),
            html.P("Filter by test:"),
            dcc.Dropdown(names, names[0], id="test-picker", multi = True), 
        ]
    ) 
    
    @app.callback(
        Output('test-explain', 'children'), 
        Input('plot-picker', 'value')
    )
    def update_chart_info(radio_selection):
        if radio_selection == 'weakness':
            text = "This test counts how many weak results are there for each test for all rounds and return the number divided by the number of rounds"
        else:
            text = ""
        return [text]
    
    app.run_server(debug=True)
    

    enter image description here