Button not working in px.scatter_mapbox

Hi everyone,
I’m using px.scatter_mapbox to plot some geographical points.
I want to show both the simple scatter where every point has the same size and also the updated plot where the size of each marker is proportional to the corresponding value assigned to that point in the geodataframe (gdf).
My code looks like this:

fig = px.scatter_mapbox(gdf, 
    lat='lat',
    lon='lon',
    size = None,
    color = 'cluster',
    hover_data=['date']
    )
fig.update_layout(
    updatemenus=[
        dict(
            type='buttons',
            direction = 'right',
            buttons=list([
                dict(
                    args=['size', None],
                    label='Sample Location',
                    method='restyle'
                ),
                dict(
                    args=['size', 'value_column'],
                    label='Value-related Size',
                    method='restyle'
                )
            ]),
            pad={'l':10,'t':10},
            showactive=True,
            x=0.11,
            xanchor="left",
            y=1.2,
            yanchor="top"
        )
    ]
)

Unfortunately the buttons show up but they don’t do anything when clicked.
I believe that args=['size', value] might be the problem here (where value is either None or the value_column).
The other possibility is that px.scatter_mapbox might work differently than plotly.graph_objects figures and thus require some special coding, but I haven’t found anything in particular to let me think this.
Also I’m following this reference (Custom buttons in Python)
Any help is appreciated :slight_smile:

@Mirk0_98
To perform the fig.data[0] restyling you should know how are defined the dicts in the list, args. Please take a look at this tutorial on method restyle https://chart-studio.plotly.com/~empet/15607/restyling-a-plotly-figure-via-a-dropdow/#/ to deduce what is wrong in your button definition.

Thank you @empet I followed the explanation and now it works perfectly.

I have one question though:
px.scatter_mapbox creates 3 traces from one single dataframe. When first calling px.scatter_mapbox() I just need to indicate the column’s name and it automatically groups the traces according to the color attributes.
When I update the fig.data[i].marker.size I have to fill in the array of sizes for that particular trace. I obtained that just by creating the figure first and saving those size arrays in one variable for each trace, so that inside the args of the updatemenus I could call those variable.
Is there a way to make the update automatically get the size values just by filling the name of the column, like when px.scatter_mapbox first creates the plot?

To be more clear I’ll post some readable pseudo code (not a minimal working example)
This one below is my working code right now


# creates 3 traces, one for each color
# this figure is the one using the correct sizes  

fig = px.scatter_map(gdf, size='value_column', color='color_column')

# get the size arrays created by px.scatter_mapbox()
size0 = fig.data[0].marker.size
size1 = fig.data[1].marker.size
size2 = fig.data[2].marker.size

# Add the buttons
fig.update_layout(
    updatemenus=[
        dict(
            type='buttons',
            direction = 'right',
            buttons=list([
                dict(
                #  . . .
                # initial figure layout (not shown)
                ),
                dict(
                   # Here I add one attribute update for each trace
                    args=[{
                        'marker' : [
                            { ## trace 0 update
                                'size' : size0,
                                'sizemode': 'area',
                                'sizeref': 800.0,
                            },
                            {  ## trace 1 update
                                'size' : size1,
                                'sizemode': 'area',
                                'sizeref': 800.0,
                            },
                            {   ## trace 2 update
                                'size' : size2,
                                'sizemode': 'area',
                                'sizeref': 800.0,
                            },
                        ]
                    }],
                    label='Updated figure',
                    method='restyle'
                ),
            ]),
        )
    ]
)

Now my question is: do you know if it is also possible to do something like this code below instead? (I know it can’t be exactly like this because I’m assigning a string to an attribute that take an array).

fig.update_layout(
    updatemenus=[
        dict(
            type='buttons',
            direction = 'right',
            buttons=list([
                dict(
                    ## . . .
                ),
                dict(
                    args=[{
                        'marker' : [
                            {
                                'size' : 'value_column',
                            },
                            {
                                'size' : 'value_column',
                            },
                            {
                                'size' : 'value_column',
                            },
                        ]
                    }],
                    label='Updated figure',
                    method='restyle'
                ),
            ]),
        )
    ]
)