✊🏿 Black Lives Matter. Please consider donating to Black Girls Code today.
🧬 Learn how to build RNA-Seq data apps with Python & Dash. Register for the May 20 Webinar!

How to access mapbox layers of a figure with a callback

Hi everyone,

I’m having issues trying to make an interactive plot of a map with different layers. I’m providing mapbox with multiple layers, and I would like those layers to be removed/added through a checklist. But since these layers are inside mapbox dictionary of the figure of my graph, I can’t find a way to access each layer individually, I can only access the figure attribute of the graph, but that would reload all the layers and consume a lot of time.

I am looking for a way to access these layers individually, even if it requires to create one callback function per checklist button.

Thanks in advance

import dash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output
import plotly.graph_objs as go

def make_figure(layers, center=dict(lat=46.679594, lon=2.636719)):
    fig = go.Figure(data=[go.Scattermapbox(
    )],
        layout=go.Layout(
        height=690,
        autosize=True,
        hovermode='closest',
        mapbox=dict(
            layers=[layers[i] for i in layers.keys()],
            accesstoken=mapbox_access_token,
            bearing=0,
            center=center,
            pitch=0,
            zoom=5
        ),
        margin={'t': 0, 'l': 0, 'r': 0, 'b': 0}
    )
    )
    return fig

app = dash.Dash(__name__)

layers = {'data_1': dict(sourcetype='geojson', source=data_1, type='fill',
                      	 opacity=0.9, color='rgba(163,22,19,0.8)'),
          'data_2': dict(sourcetype='geojson', source=data_2, type='fill', opacity=0.2,
                         color='rgba(20,22,120,0.8)')
          }

fig = make_figure(layers)

app.layout = html.Div(children=[
    html.H1(children="My application"),

    html.Div(children=[dcc.Graph(id='map', figure=fig,
                                 style={'height': '690px', 'width': 'auto'})
                       ],
             style={'height': '690px', 'width': '80%',
                    'display': 'inline-block', 'vertical-align': 'top'}
             ),
    html.Div(children=[dcc.Checklist(id="checklist", options=[
        {'label': 'Data 1', 'value': 'data_1'},
        {'label': 'Data 2', 'value': 'data_2'}],
        values=['data_1', 'data_2'])
    ], style={'height': '690px', 'width': '20%', 'display': 'inline-block',
              'horizontal-align': 'right'})
], style={'height': '750px', 'width': 'auto'})

@app.callback(
    Output(component_id='map', component_property='figure'),
    [Input(component_id='checklist', component_property='values')]
)
def update_output_div(input_value):
    new_layers = {k: layers[k] for k in input_value}
    new_figure = make_figure(new_layers)
    return new_figure


if __name__ == '__main__':
    app.run_server(host='127.0.0.1', port=10020, debug=True)

Hi, did you ever figure this out? I am also curious.

Thanks