Hi everyone,
I have a complex map, with many polygons. I want te create a dash app where I load my polygons on a map only once using coroplethmapbox and then add a drop-down menu to update the z value inside the polygons without reloading the polygons (geojson).
Any idea or link to similar question
Thanks,
Laurent
Hi @ltestut1 welcome to the forums. You could update the z- value via a clientside callback. Here an example:
- the chart is loaded with the initial values
- on app startup these initial values are written into the clientside store
- a callback is fired if a value is selected from the drop down, the z- values are updated accordingly
Keep in mind, that only the z- values are getting updated, the colorscale (min/max) is not updated. If needed, you would have to to this in the callback too.
from dash import Dash, dcc, Input, Output, State
import dash_bootstrap_components as dbc
from plotly_docs import fig
# ^^ this is actually just the figure of the first example here: https://plotly.com/python/mapbox-county-choropleth/
app = Dash(
__name__,
external_stylesheets=[dbc.themes.BOOTSTRAP]
)
app.layout = dbc.Container(
[
dbc.Row(
dcc.Graph(
id='graph',
figure=fig
)
),
dbc.Row([
dcc.Dropdown(
id='drop',
options=[
{'label': 'initial', 'value': 1.0},
{'label': 'half', 'value': 0.5},
{'label': 'double', 'value': 2.0}
]
),
dcc.Store(id='store')
])
],
fluid=True
)
app.clientside_callback(
"""
function(dummy_val, fig) {
return fig['data'][0]['z']
}
""",
Output('store', 'data'),
Input('drop', 'options'),
State('graph', 'figure')
)
app.clientside_callback(
"""
function(drop_val, fig, init_val) {
newFig = JSON.parse(JSON.stringify(fig))
if (drop_val == 1.0) {
newFig['data'][0]['z'] = init_val
} else {
newFig['data'][0]['z'] = init_val.map(element => element * drop_val)
}
return newFig
}
""",
Output('graph', 'figure'),
Input('drop', 'value'),
State('graph', 'figure'),
State('store', 'data'),
prevent_initial_call=True
)
if __name__ == '__main__':
app.run(debug=True, port=8050)
plotly_docs.py
from urllib.request import urlopen
import plotly.express as px
import pandas as pd
import json
with urlopen('https://raw.githubusercontent.com/plotly/datasets/master/geojson-counties-fips.json') as response:
counties = json.load(response)
df = pd.read_csv("https://raw.githubusercontent.com/plotly/datasets/master/fips-unemp-16.csv",
dtype={"fips": str})
fig = px.choropleth_mapbox(
df,
geojson=counties,
locations='fips',
color='unemp',
color_continuous_scale="Viridis",
range_color=(0, 12),
mapbox_style="carto-positron",
zoom=3, center={"lat": 37.0902, "lon": -95.7129},
opacity=0.5,
labels={'unemp': 'unemployment rate'}
)
fig.update_layout(margin={"r": 0, "t": 0, "l": 0, "b": 0})
1 Like
Hi AIMPED,
Thanks a lot for your solution. Do you know if I can use the dash Patch object I recently discover to update the z value without using a clientside callback?
Hi @ltestut1, yes, the Patch() should work too. It allows you to update your figure partially.