Info about bbox in clickData

I have a dcc.Graph div with a 3D mesh displayed. There’s a callback that gets triggered on clicking on the mesh. Now, in this clickData info, there are many keys such as x, y, z (coordinates of the closest mesh vertex), pointNumber , trace and bbox. I couldn’t find any info about what bbox is - it gives two coordinates x1, y1, x2, y2, and on each trigger, x1=x2 and y1=y2. What coordinates are these and how are they affected by the mesh and/or the layout of the dcc.Graph div?

hi @ac13
Could you please share the code with us so we can run it on our computer and see the same info when using the clickData?

Hello, thanks for the response!

A sample code such as this should be sufficient:

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


base_url = "https://raw.githubusercontent.com/plotly/datasets/master/ply/sandal"
dataframe = pd.read_csv(base_url + '-ply.csv') 

app = Dash(__name__)

app.layout = html.Div([
    dcc.Graph(id="graph"),
])


@app.callback(
    Output("graph", "figure"), 
    Input("graph", "clickData"))
def display_mesh(n_click):
    df = dataframe
    print(n_click)
    fig = go.Figure(go.Mesh3d(
        x=df.x, y=df.y, z=df.z, 
        i=df.i, j=df.j, k=df.k, 
        facecolor=df.facecolor))
    return fig


app.run_server(debug=True)

HI @ac13, interesting question. So to figure this out, I had to create a dash app. The bbox refers to the position of the click coordinate in the div. I guess bbox stands for bounding box and are the coordinates of a box which encloses the clicked item.

The values of the coordinates given by the event listener are almost identical with the bbox values for a figure created with px.imshow() and differs slightly for a go.Scatter3d() trace. I guess the latter is due to the “snap radius” for the click data.

from dash import Dash, html, dcc, Input, Output, State
import plotly.express as px
import plotly.graph_objects as go
import numpy as np
import json
from dash_extensions import EventListener

# create some data
x, y, z = np.meshgrid(np.linspace(0,1,2), np.linspace(0,1,2), np.linspace(0,1,2))
x = x.flatten()
y = y.flatten()
z = z.flatten()

# create figures
scatter = go.Figure(go.Scatter3d(x=x, y=y, z=z, mode='markers', marker={'size': 3}))
image = px.imshow(img=np.ones(shape=(600, 600)))

app = Dash(
    __name__,
    external_stylesheets=[
        "https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css",
    ]
)

app.layout = html.Div(
    [
        html.Div(
            className='col-6',
            children=EventListener(
                html.Div([
                    # ^^ necessary because EventListener is somehow buggy
                    #    with the dcc.Graph() directly
                    dcc.Graph(
                        id='graph',
                        figure=image,
                    ),
                    dcc.Graph(
                        id='graph_1',
                        figure=scatter,
                    )
                ],
                    style={
                        'border-width': '1px',
                        'border-style': 'solid',
                        'border-color': 'black'
                    }
                    # ^^ just for visualising of the parent div
                ),
                events=[{"event": "click", "props": ['x', 'y']}],
                logging=True,
                id="event_listener"
            )
        ),
        html.Div(
            id='out_0',
            className='col-2'
        ),
        html.Div(
            id='out_1',
            className='col-2'
        ),
        html.Div(
            id='out_2',
            className='col-2'
        ),
    ],
    className='row'
)


@app.callback(
    Output('out_0', 'children'),
    Output('out_1', 'children'),
    Output('out_2', 'children'),
    Input('graph', 'clickData'),
    Input('graph_1', 'clickData'),
    Input('event_listener', 'n_events'),
    State('event_listener', 'event'),
    prevent_initial_call=True
)
def update(click_data, click_data_1, n_events, event):
    return [
        html.Pre([html.H5('click data image'), json.dumps(click_data, indent=3)]),
        html.Pre([html.H5('click data scatter'), json.dumps(click_data_1, indent=3)]),
        html.Pre([html.H5('event listener'), json.dumps(event, indent=3)]),
    ]


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

Hello. Thanks a lot for the explanation and the example app. :grin:
So, the bbox data is the 2D coordinate (same/similar to the event listener info), with the origin at top left of the current div of the dcc.Graph element.