Need help connecting a DCC dropdown to a Choropleth map

I’ve tried StackOverflow and someone mentioned I try here. I have a dataframe and I can make a Choropleth map from each individual data column (% Population Change and Unemployment Rate). I’d like to connect a dropdown to the graph. Like I said, I can create a static Dash Choropleth map from one of the column, but can’t connect the dropdown to the graph.

My stackoverflow question: python - How to connect a Plotly Dash dropdown to a Choropleth map? - Stack Overflow

There’s a bunch of code before to create this DataFrame. Here’s the first five lines.

FIPS       Geographic Area State  4/1/2010 Census  4/1/2020 Census  % Population Change  Unemployment Rate
0   22001                Acadia    LA            61787            57576            -6.815350                3.6
1   22003                 Allen    LA            25747            22750           -11.640191                4.0
2   22005             Ascension    LA           107215           126500            17.987222                2.9
3   22007            Assumption    LA            23416            21039           -10.151179                5.3
4   22009             Avoyelles    LA            42071            39693            -5.652350                3.7

And here’s the rest of the code.

import pandas as pd
import requests
from bs4 import BeautifulSoup
from urllib.request import urlopen
import json
import dash
import plotly.graph_objs as go
import dash_html_components as html
import dash_core_components as dcc
from dash.dependencies import Input, Output
import plotly.express as px


def display_chart():
   
    # There's a bunch of code before this, but the dataframe works fine on separate Choropleth maps. I would like an interactive map using the drop down.
    df = pd.merge(df4, df5, on="Geographic Area", how='inner')

    # print(df) The output is printed in this forum question.

    app = dash.Dash()

    app.layout = html.Div([
        html.H2('Financial Genome Project'),
        dcc.Dropdown(
            id='census_type',
            options=[{"label": x, "value": x}
                     for x in df.columns[5:]],
            value=df.columns[0],
            clearable=False,
            style={'width': 300},
            placeholder="Select a census data type"
        ),
        html.Hr(),
        dcc.Graph(id="choropleth-chart"),
    ])

    @app.callback(
        Output("choropleth-chart", "figure"),
        [Input("census_type", "value")]
    )
    def display_choropleth(census_type):
        fig = px.choropleth(df, geojson=counties,
                            locations='FIPS',
                            color=census_type,
                            color_continuous_scale="rdylgn_r",
                            range_color=(0, 8),
                            scope="usa",
                            hover_name='Geographic Area',
                            # labels={'% Change': 'Population % Change'}
                            )

        # fig.update_layout(margin={"r": 0, "t": 0, "l": 0, "b": 0})
        fig.update_geos(fitbounds='locations', visible=False)
        return fig

    app.run_server(debug=True)


display_chart()

This is what I get. No Choropleth map and callback errors.

Hi @bjone6 and welcome to the community!

What version of Dash are you using?
The error could be rising from the recent upgrade of the werkzeug library as mentioned in this post - Dash ImportError: cannot import name ‘get_current_traceback’ from ‘werkzeug.debug.tbtools’ - Dash Python - Plotly Community Forum

Thanks for the recommendation, but it didn’t work. I did upgrade everything to the new version as you mentioned in the post though. I don’t think my code is right to be honest.

I was able to run your code without any errors with the few lines data you provided above.
Though I am confused why have you set the value of your dropdown value=df.columns[0] which is not included in your options list
options=[{"label": x, "value": x} for x in df.columns[5:]].

Also another reason for the error you are getting could be the time taken by your callback to update the figure, even with the above few lines of data the callback update time was very high

Creating the choropleth figure with your entire data on each update could be expensive on the server, you can try filtering the df used in the callback.

1 Like

That’s great news that the code works but upsetting that it’s not working for me. Any suggestions on what I can do to run it myself?

As for the time, it’s probably due to my inexperience. I’m happy to take any suggestions to improve the code.

1 Like

Not sure why you can’t run it at your end, maybe try a clean installation of the libraries and try again.

Few suggestions I can add are:

  1. Importing dash libraries
    With Dash 2.0 and above it is recommended to use the simpler import statement
from dash import Dash, callback, html, dcc, dash_table, Input, Output, State
  1. Callback Signature
    Placing the Outputs, Inputs statements in a list is not required, just keep them comma separated.
    @app.callback(
        Output("choropleth-chart", "figure"),
        Input("census_type", "value")
    )
  1. You may want to use a loading component to wrap your dcc.Graph, this will show a loading animation till your callback executes and updates your graph.

  2. Try supplying a smaller subset of your df to the callback and see if that works, also checkout other approaches like using Plotly and datashader with Python which can handle large datasets.