✊🏿 Black Lives Matter. Please consider donating to Black Girls Code today.
🐍Plotly, Coiled CEOs Discuss Partnering & ML Experts show us how Dash + Dask apps work Register for the Webinar.

Highlighting choropleth polygon when clicked (or add some marker to it)

I have a choropleth map that covers each state in the U.S. and would like to be able to highlight the polygon when the user clicks on it by way of either increasing the transparency or adding some sort of marker to it (ex: freezing hover tooltip). Is there a way to achieve this?

I came across this article, which is exactly what I’m looking to do but because the geojson file I have is quite large and the graph is redrawing the entire shape due to how the callback works, it takes a while for the transparency to change when clicked - making the app not user-friendly.

Please help!

One possible approach to achieve this functionality is to draw the “normal” data in one layer, and then add the selection as another layer on top. I have previously done this in dash-leaflet where the polygons in the selection layer were filtered via the filter option of the GeoJSON component.

https://leafletjs.com/reference-1.7.1.html#geojson-filter

@Emil thank you for the suggestion. Would it be possible for you to show a brief working code for the scenario that I have? Currently, I have a go.Choropleth and go.Scattermapbox as two traces passed into go.Figure to show latlong datapoints underlayed by the choropleth geojson shape files. That part of the code is working well but I just need to add a marker to the polygon when the user clicks it and retrieve the name of that polygon from clickData to match a column in a dataframe, so I can display the data about that polygon.

I have gone through the link you sent me but haven’t been able to achieve something like what I described.

Any help would be much appreciated.

Here is a small example,

import dash_html_components as html
import dash_leaflet as dl
from dash import Dash
from dash.dependencies import Output, Input
from dash_extensions.javascript import assign

geojson_url = "https://raw.githubusercontent.com/PublicaMundi/MappingAPI/master/data/geojson/us-states.json"
# Create javascript function that filters on feature name.
geojson_filter = assign("function(feature, context){return context.props.hideout == feature.id;}")
# Create example app.
app = Dash()
app.layout = html.Div([
    dl.Map(children=[
        dl.TileLayer(),
        # The "normal" geojson layer, colored in grey.
        dl.GeoJSON(url=geojson_url, zoomToBounds=True, options=dict(style=dict(color="grey")), id='geojson'),
        # The "selected" geojson layer, colored in blue (default).
        dl.GeoJSON(url=geojson_url, options=dict(filter=geojson_filter), id="selected")
    ], style={'width': '100%', 'height': '50vh', 'margin': "auto", "display": "block"}, id="map"),
])
# Link click to geojson hideout prop (could also be done with a normal callback, but that is slower).
app.clientside_callback("function(feature){return feature.id;}",
                        Output('selected', 'hideout'), Input('geojson', 'click_feature'))


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

While a large geojson might increase initial load time, I would expect the performance of the click update to remain fast.

click

I’m getting ImportError “cannot import name ‘assign’ from ‘dash_extensions.javascript’” when I copy paste your script and try to run it. I have pip installed dash-leaflet and dash-extensions

The assign function is relatively new. Have you updated to the latest version of dash-extensions (0.0.55)?

Thanks @Emil . Is it possible to pass go.Scattermapbox into dl.Tile? Something like this dl.TileLayer(go.Scattermapbox())? I need to add a scatter plot on a map with multiple traces (i.e. different colored circle) to show locations on a map in addition to the choropleth. Thank you.