You can also do it with plotly and px.choropleth_mapbox.
### Version Dash Plotly - Highlighting a selected feature
from dash import Dash, Output, Input, State, dcc, no_update # pip install Dash
from urllib.request import urlopen
import geopandas as gpd # pip install geopandas
import plotly.express as px # pip install plotly
import json
with urlopen('https://raw.githubusercontent.com/PublicaMundi/MappingAPI/master/data/geojson/us-states.json') as response:
gdf = gpd.GeoDataFrame.from_features(json.load(response))
def create_figure_us_states(): # function to generate first figure
fig = px.choropleth_mapbox(gdf,
geojson=gdf.geometry.__geo_interface__,
locations=gdf.index,
opacity = 0.3,
hover_data =["name","density"],
mapbox_style="open-street-map",
center={"lat": 39.2094813, "lon": -110.1607186},
zoom=2)
fig.update_layout(margin={"r":0,"t":0,"l":0,"b":0})
fig.update_layout(showlegend=False)
fig.update_coloraxes(showscale=False)
return fig
# Create small example app.
app = Dash()
app.layout = dcc.Graph(figure=create_figure_us_states(),config={'displayModeBar': False},id="map-country-us",style={'height':'60vh','width':'100%'})
# Create callback -- Highlighting a selected feature
@app.callback(Output("map-country-us", "figure",allow_duplicate=True),Input('map-country-us', 'clickData'),State('map-country-us','figure'),prevent_initial_call=True)
def update_figure(click_data,figure):
if click_data is None:
return no_update
# Check if properties is in the dict or add it (Need it to create a geodataframe)
for feature in figure["data"][0]["geojson"]["features"]:
if 'properties' in feature:
break
else:
feature.update({"properties":{}})
# Create the geodataframe gdf_
gdf_ = gpd.GeoDataFrame.from_features(figure["data"][0]["geojson"]["features"]) # Column geometry
for i in range (0,len(figure["data"][0]["customdata"])):
gdf_.loc[i,'density'] = figure["data"][0]["customdata"][i][1] #Column Density
gdf_.loc[i,'name'] = figure["data"][0]["customdata"][i][0] #Column Name
gdf_["color"]=gpd.GeoDataFrame(figure["data"][0]["z"]) #Column Color
# Extract id of the country with a simple click #
country_id = click_data['points'][0]['location']
if gdf_.loc[country_id,'color'] == 0:
gdf_.loc[country_id,'color'] = 1
else:
gdf_.loc[country_id,'color'] = 0
# Create a new figure with gdf_
new_fig = px.choropleth_mapbox(gdf_,
geojson=gdf_.geometry.__geo_interface__,
locations=gdf_.index,
opacity = 0.3,
color = gdf_.color,
color_continuous_scale = ['red', 'blue'],
range_color = [0, 1],
hover_data =["name","density"],
mapbox_style="open-street-map",
center={"lat": 39.2094813, "lon": -110.1607186},
zoom=2)
new_fig.update_layout(margin={"r":0,"t":0,"l":0,"b":0})
new_fig.update_layout(showlegend=False)
new_fig.update_coloraxes(showscale=False)
return new_fig
### Run app ###
if __name__=='__main__':
app.run_server(debug=True, port=8070)