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)
Hello. Thanks a lot for the explanation and the example app.
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.