Updating fig.layout.map.layers.opacity on a choropleth_map

Hi all,

I am working on plotting satellite images as a background layer on a choropleth map. I successfully added the images to the map using the following code:

def init():
    gdf = ... # geopandas dataframe
    img = ... # numpy array

    fig = px.choropleth_map(
        gdf,
        geojson=gdf.geometry,
        locations=gdf.index,
        opacity=0.5,
        center={"lat": center_y, "lon": center_x},
        zoom=zoom,
        color='Type',
    )

    fig_img = px.imshow(img)
    fig_img.update_layout(
                        width=img.shape[1] // reduction_factor,
                        height=img.shape[0] // reduction_factor,
                        xaxis_showticklabels=False, 
                        yaxis_showticklabels=False,
                        margin=dict(t=0, r=0, b=0, l=0))  ### Very important to set margins=0!!!!
        
    b64 = base64.b64encode(fig_img.to_image(format="png"))
    img_source = "data:image/png;base64," + b64.decode("utf-8")
    
    map_dict = dict(
        layers=[
            dict(
                below ='',
                source = img_source, 
                sourcetype= "image", 
                coordinates =  [[x_min, y_max], 
                                [x_max, y_max], 
                                [x_max, y_min], 
                                [x_min, y_min]],
                opacity=0.1
                ),
            ]
        )         
    fig.update_layout(map=map_dict)

    return fig

I also implemented a callback function to control the opacity of both the satellite images and the choropleth map. Below is the code for the callback:


@callback(
    Output('map-plot', 'figure', allow_duplicate=True),
    [
    Input('opacity-slider', 'value'),
    State('map-plot', 'figure'),
    State('project-dropdown', 'value'),
    State('stage-dropdown', 'value')
    ],
    prevent_initial_call=True
    )
def update_opacity(value, fig, selected_project, selected_stage):
    if not selected_project or not selected_stage:
        return no_update
    
    fig = go.Figure(fig)
    fig.update_traces(marker=dict(opacity=value/100))
    
    if "map" in fig.layout:
        fig.update_layout(map=dict(layers=[dict(opacity=value/100),]))
        # fig.update_layout(map=dict(layers=[dict(visible=False),]))
        print(fig.layout)
    
    return fig

Here are two screenshots of the map to demonstrate the current state:


Problem: In the callback, I can successfully update the opacity for the choropleth map. However, although the fig.layout object reflects changes to the opacity of the RGB satellite images, the visual output does not update. Other properties (e.g., visible) work as expected, but opacity seems to have no effect.

I am wondering:

  1. Is there an issue with my code or the way I am updating the opacity?
  2. Is it not possible to dynamically update the opacity of plotted images on a map, or could this be a limitation/bug in the library?

Thank you so much for your help!