Making marker size dynamic when changing browser sizes

I’ve created a scatterplot using plotly express in plotly dash that is supposed to function as a timeline with all markers across one Y value (Gantt Charts & Bar graphs did not work in this scenario). I used large marker sizes to fill the screen, and I am wondering if there is any way for the marker size to dynamically change sizes so that when the window size increases or decreases, the markers won’t overlap each other nor spread apart?

Welcome to the forums @stapler.

Yes, this is possible. What I’m doing here is adding a eventListener for the window size. If resized, a dummy elements gets clicked and the callbacks for the change of the marker size get triggered. I could have made the last callback clientside too.

from dash import Dash, dcc, html, Input, Output, Patch
import plotly.graph_objects as go

app = Dash(__name__)

app.layout = html.Div(
    [
        dcc.Store(id="dimensions"),
        html.Div(id='dummy'),
        dcc.Graph(
            id='graph',
            figure=go.Figure(
                data=go.Scatter(
                    x=[1, 2, 3],
                    y=[1, 2, 3],
                    mode='markers',
                )
            )
        )
    ]
)

# add event listener for window resizing
app.clientside_callback(
    """
    function(trigger) {
        function dummyClick() {
            document.getElementById('dummy').click()
        };
        
        window.addEventListener('resize', dummyClick)
        return window.dash_clientside.no_update
    }
    """,
    Output("dummy", "style"),
    Input("dummy", "style")
)

# store current dimension in store
app.clientside_callback(
    """
    function updateStore(click) {
        var w = window.innerWidth;
        var h = window.innerHeight; 
        return [w, h]
    }
    """,
    Output('dimensions', 'data'),
    Input('dummy', 'n_clicks')
)


# update marker size
@app.callback(
    Output('graph', 'figure'),
    Input('dimensions', 'data'),
)
def change_size(data):
    # unpack the current window dimensions
    w, h = data

    # create patch for figure update
    patched = Patch()

    # scale marker size depending on window width (w)
    patched['data'][0]['marker']['size'] = w/25

    return patched


if __name__ == "__main__":
    app.run(debug=True)

mred cscb

3 Likes