NoLayoutException: Layout must be a dash component or a function that returns a dash component

app = dash.Dash(__name__)


app.layout = html.Div([
                        dcc.Dropdown(id = 'demo-dropdown', 
                                     options = [{'label':str(item) , 'value':item } for item in df_copy['country_txt'].unique()],
                                     
                                    ),
             #dcc.Graph(id = 'Plot2', figure = fig2)
                      ]),
html.Div([dcc.Graph(id = 'id-graph', config = {'scrollZoom' : True})])

@app.callback(
     Output('id-graph', 'figure'),
    [Input('demo-dropdown', 'value')])
def update_output(value):
    df_sub = df_copy.loc[df_copy['country_txt'] == value]
    
    #create graph
    location = [go.Scattermapbox(lon = df_sub['longitude'], lat = df_sub['latitude'] , mode = 'markers',hoverinfo= 'text' )]
    
    # return graph
    return {'data': location , 'layout':go.layout(uirevision = 'foo' , hovermode = 'closest' , hoverdistance = 2 , mapbox =dict(accesstoken = mapbox_access_token))}
    

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

Traceback Error:

---------------------------------------------------------------------------
NoLayoutException                         Traceback (most recent call last)
<ipython-input-42-705f648addcb> in <module>
      6                         dcc.Dropdown(id = 'demo-dropdown', 
      7                                      options = [{'label':str(item) , 'value':item } for item in df_copy['country_txt'].unique()],
----> 8                                      value = 'India'
      9                                     ),
     10              #dcc.Graph(id = 'Plot2', figure = fig2)

~\Anaconda3\envs\machine_learning\lib\site-packages\dash\dash.py in layout(self, value)
    463     @layout.setter
    464     def layout(self, value):
--> 465         _validate.validate_layout_type(value)
    466         self._layout_is_function = isinstance(value, patch_collections_abc("Callable"))
    467         self._layout = value

~\Anaconda3\envs\machine_learning\lib\site-packages\dash\_validate.py in validate_layout_type(value)
    325     if not isinstance(value, (Component, patch_collections_abc("Callable"))):
    326         raise exceptions.NoLayoutException(
--> 327             "Layout must be a dash component "
    328             "or a function that returns a dash component."
    329         )

NoLayoutException: Layout must be a dash component or a function that returns a dash component.

I am not able to figure out how to deal with this. Even after removing the value and putting placeholder = ‘Select a country…’ , this gives same error at same line.

df_copy contains column country_txt which has country names.

Hi @matsujjudes and welcome to the Dash Community!

All of the layout components need to be contained within the app.layout.
Try making the layout like this:

app.layout = (
    html.Div(
        [
            dcc.Dropdown(
                id="demo-dropdown",
                options=[
                    {"label": str(item), "value": item}
                    for item in df_copy["country_txt"].unique()
                ],
            ),
            # dcc.Graph(id = 'Plot2', figure = fig2)
            html.Div([dcc.Graph(id="id-graph", config={"scrollZoom": True})]),
        ]
    ),
)

It looks a lot different, but the only real change was moving ]), so the layout included the div with the graph.

It was reformatted using Black - which is a great tool, not only for making your code look nice (and PEP8 compliant) but it also makes it much easier to find bugs like this. (It’s saved me hours!)

2 Likes

Thanks…I didn’t know formatting a brackets would cause me so much trouble. I will surely try formatting extension.