Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to capture the data of the drawn shapes by the mouse in Dash

So I have this simple python dash application in which I've laid out a graph and a button. My goal is this: when I press the button, I want to retrieve the shapes that have been drawn.

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

app = dash.Dash(__name__)
fig = go.Figure()

app.layout = html.Div([
                        dcc.Graph(id = "graph-pic", className="graph-pic", figure=fig, config={'modeBarButtonsToAdd':['drawrect', 'eraseshape']}),
                        html.Button("Shape count", id = "shape-count-button")
                    ])
        
fig.add_shape(editable=True, x0=-1, x1=0, y0=2, y1=3, xref='x', yref='y')

@app.callback(
    Output("graph-pic", "figure"),
    Input("shape-count-button", "n_clicks")
)
def on_shape_count_button_pressed(n_clicks):
    trigger_id = dash.callback_context.triggered_id

    if trigger_id == "shape-count-button":
        print("Shape count: " + str(len(fig.layout.shapes)))
        print(fig.layout.shapes)
    
    return dash.no_update

if __name__ == "__main__":
    app.run_server()

Dash app When I press the button, it only prints the first shape that I've added through code... and NOT the ones that I've drawn on the graph with the draw rectangle tool.

Output:

Shape count: 1
(layout.Shape({
    'editable': True, 'x0': -1, 'x1': 0, 'xref': 'x', 'y0': 2, 'y1': 3, 'yref': 'y'
}),)

Any hint would be appreciated!

like image 802
Cosmin Ivan Avatar asked Oct 18 '25 03:10

Cosmin Ivan


1 Answers

You should use relayout_data to detect all the drawn shapes on the graph, and then you can parse the desired data as you would:

import dash
import json
import plotly.graph_objects as go
from dash import html, dcc, Input, Output, State

app = dash.Dash(__name__)
fig = go.Figure()

app.layout = html.Div([
                        dcc.Graph(id = "graph-pic", className="graph-pic", figure=fig, config={'modeBarButtonsToAdd':['drawrect', 'eraseshape']}),
                        html.Button("Shape count", id = "shape-count-button"),
                        html.Div(id="text")
                    ])
        
fig.add_shape(editable=True, x0=-1, x1=0, y0=2, y1=3, xref='x', yref='y')

@app.callback(
    Output("text", "children"),
    Input("shape-count-button", "n_clicks"),
    Input("graph-pic", "relayoutData"),
)
def on_shape_count_button_pressed(n_clicks, relayout_data):
    
    trigger_id = dash.callback_context.triggered_id

    if trigger_id == "shape-count-button":
        text_lst = "Shape count: " + str(len(fig.layout.shapes))
        text_lst += str(fig.layout.shapes)
        
        if "shapes" in relayout_data:
            text_lst += json.dumps(relayout_data["shapes"], indent=2)
            
        return text_lst
    
    return dash.no_update

if __name__ == "__main__":
    app.run_server()

Output enter image description here

like image 101
Phoenix Avatar answered Oct 20 '25 16:10

Phoenix



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!