✊🏿 Black Lives Matter. Please consider donating to Black Girls Code today.
🐇 Announcing Dash VTK for 3d simulation graphics. Check out the March webinar.

Add buttons to Scattermapbox (to zoom in on some places, using the relayout method)

Hello there :rocket:,

I tried to add buttons to a Scattermapbox object in order to be able to zoom in on certain places but it doesn’t seem to work. Buttons showed up, and I was able to click on them, but nothing happened. Is it an expected behavior? Did I miss or fail something?

You can replicate it by running the following code snippet (based on this example) :

import plotly.graph_objects as go

lat = ['38.91427', '38.91538', '38.91458',
       '38.92239', '38.93222', '38.90842',
       '38.91931', '38.93260', '38.91368',
       '38.88516', '38.921894', '38.93206',
       '38.91275']

lon = ['-77.02827', '-77.02013', '-77.03155',
       '-77.04227', '-77.02854', '-77.02419',
       '-77.02518', '-77.03304', '-77.04509',
       '-76.99656', '-77.042438', '-77.02821',
       '-77.01239']

coffee = ["The coffee bar", "Bistro Bohem", "Black Cat",
        "Snap", "Columbia Heights Coffee", "Azi's Cafe",
        "Blind Dog Cafe", "Le Caprice", "Filter",
        "Peregrine", "Tryst", "The Coupe",
        "Big Bear Cafe"]

fig = go.Figure(go.Scattermapbox(lat=lat, lon=lon, mode='markers', marker=go.scattermapbox.Marker(size=9), text=coffee))

fig.update_layout(autosize=True, hovermode='closest',
                  mapbox=dict(style='open-street-map', bearing=0, center=dict(lat=38.92, lon=-77.07), pitch=0, zoom=10))

buttons = []
for lat_, lon_, coffee_ in zip(lat, lon, coffee):
    buttons.append({'label': coffee_, 'method': 'restyle', 'args': ['mapbox', {
        'center': {'lat': lat_, 'lon': lon_},
        'zoom': 14
    }]})

fig.update_layout(updatemenus=[{'type': 'buttons', 'buttons': buttons}])

fig.show()

Thanks a lot !

Hi @acoque,

Your are updating the plot layout, hence the Plotly method to be called should be 'relayout' , not 'restyle'. Moreover, in an arg definition, an attribute of a nested dict must be accessed
following the javascript rule, not Python.
With this buttons definition your code works:

buttons = []
for lat_, lon_, coffee_ in zip(lat, lon, coffee):
    buttons.append({'label': coffee_, 
                    'method': 'relayout', 
                    'args': [{'mapbox.center.lat': lat_,
                              'mapbox.center.lon': lon_,
                              'mapbox.zoom': 14}]})

Thanks a lot for your quick answer ! :upside_down_face:

About the method to use, I do agree with you. I do use the relayout method in my “real code” and I just made a mistake here when adapting the example (my bad :sweat_smile:).

However, I wasn’t aware that one has to follow the Javascript rule (and not the Python one) in order to correctly specify attributes (of a nested dictionary). I believe it is not mentioned anywhere in the documentation :confused:

I tried your snippet and it works fine :ok_hand: Thank you so much for your help !