Hi,
I’m doing a callback on my mapbox figure. However it does not succeed completely. The reason is a bit unclear to me. The dashboard works as following.
- you can click on a theme
- you can click on a dataset
- the figure updates according to the dataset
These number are also indicated in the figure below
The first issue is that step 2 does not exist at the start but only when a theme is selected. Therefore, the callback between step 2 and 3 gives an error which can also be seen in the figure. Moreover, when I click on either of the datasets nothing happens.
Below is my code:
from dash import Dash, html, dcc, Input, Output
from dash.exceptions import PreventUpdate
import dash_bootstrap_components as dbc
import plotly.express as px
import pandas as pd
import dask.dataframe as dd
import os
import base64
# initialize dash app
app = Dash(external_stylesheets=[dbc.themes.BOOTSTRAP])
# load shoreline monitor dataframe
path_shorelineNL = r'P:\1000545-054-globalbeaches\15_GlobalCoastalAtlas\datasets\ShorelineMonitor\shoreline_NL.csv'
df = pd.read_csv(path_shorelineNL)
# Icons
test_png = 'dash/assets/deltares.png'
test_base64 = base64.b64encode(open(test_png, 'rb').read()).decode('ascii')
# initialize figure
fig = px.scatter_mapbox(zoom= 7, height=1000, center = {'lat': 52.6, 'lon':5})
fig.update_layout(mapbox_style="open-street-map", margin=dict(l=0,r=0,b=0,t=0), paper_bgcolor="Black")
# create theme buttons
button_style = {'color': 'white', 'font-size': 20, 'width': '100%', 'border-color': 'dark', 'textAlign': 'left'}
button_group = dcc.RadioItems(
[
{"label": html.Div(["Shoreline Development"], style= button_style), "value": 1},
{"label": html.Div(["Beach State"], style= button_style), "value": 2},
{"label": html.Div(["Sea Conditions"], style= button_style),"value": 3},
],
value= 0,
id="choose_theme",
style= {'width': '100%'},
className="btn-group-vertical",
inputClassName="btn-check",
labelClassName="btn",
)
# Make initial app layout
app.layout = html.Div(children=[
dbc.Card(
dbc.CardBody([
dbc.Row([
dbc.Row([
dbc.Col(html.Div(id = 'Theme_container',
children = [ dbc.Row([
dbc.Row([
html.Div([html.Img(src = 'data:image/png;base64,{}'.format(test_base64), style = {'width': '30%'}),
html.Div(children='Dutch Coastal Atlas', style = {'color': 'white', 'textAlign': 'left', 'font-size': 15})], style = {'display': 'inline-block'})
]),
]),
html.Br(),
html.H2(children = 'Themes', style = {'color': 'white', 'textAlign': 'left'}),
html.Br(),
button_group
]), width = 2, style = {'background-color': 'dark'}),
dbc.Col(html.Div(children = dcc.Graph(id='mapbox',figure= fig)), width = 6, style = {'background-color' : 'dark'}),
dbc.Col(html.Div(id = 'Data_container',
children = []), width = 4, style = {'background-color': 'dark'})
])
])
])
, color = 'dark')
])
@app.callback(
[Output(component_id = 'Data_container', component_property = 'children')],
[Input(component_id = 'choose_theme', component_property = 'value')]
)
def update_data_container(value):
if value == 1:
container = [
dbc.Col([
html.Br(),
html.H2('Shoreline Development', style = {'color': 'white', 'textAlign': 'center'}),
html.Br(),
html.Br(),
dcc.RadioItems(
[
{
"label": html.Div(['Transects'], style = {'color' : 'white'}), "value": 1,
},
{
"label": html.Div(['Continious'], style = {'color' : 'white'}),"value": 2,
},
],
labelStyle={'display': 'block'},
value = 0,
inline= False,
id= 'data_shorelinedevelop'
#style= {'width': '100%'}
)
])
]
return container
if value == 2:
container = [
dbc.Col([
html.Br(),
dbc.Row(html.H2('Beach State', style = {'color': 'white', 'textAlign': 'center'}))
])
]
return container
if value == 3:
container = [
dbc.Col([
html.Br(),
dbc.Row(html.H2('Sea Conditions', style = {'color': 'white', 'textAlign': 'center'}))
])
]
return container
else:
raise PreventUpdate
@app.callback(
Output(component_id = 'mapbox', component_property = 'figure'),
Input(component_id = 'data_shorelinedevelop', component_property = 'value')
)
def update_figure(value):
print(value)
if value == 1:
fig_new = px.scatter_mapbox(
df, lat="Intersect_lat",
lon="Intersect_lon",
hover_name="transect_id",
hover_data=["country_name", "changerate"],
labels = {'country_name' : 'Country', 'Intersect_lat': 'Latitude', 'Intersect_lon': 'Longitude'},
color_discrete_sequence=["black"], zoom= 7, height=1000, center = {'lat': 52.6, 'lon':5})
fig_new.update_layout(mapbox_style="open-street-map", margin=dict(l=0,r=0,b=0,t=0), paper_bgcolor="Black")
fig_new.update_traces(marker={'size': 15})
return fig_new
if value == 2:
fig_new = px.scatter_mapbox(zoom= 7, height=1000, center = {'lat': 40, 'lon':5})
fig_new.update_layout(mapbox_style="open-street-map", margin=dict(l=0,r=0,b=0,t=0), paper_bgcolor="Black")
return fig_new
else:
raise PreventUpdate
if __name__ == '__main__':
app.run_server(debug=True)
Also if anyone knows how to fix the following:
- Aline the pictogram and the text in the upper left horizontally
- Align the label and selection box of the radio buttons horizontally.
Thanks in advance,
Dante