# Modebar interactions as a callback property

**URL:** <https://community.plotly.com/t/modebar-interactions-as-a-callback-property/86100>\
**Category:** Dash Python\
**Created:** [July 25, 2024, 8:55am UTC](https://community.plotly.com/t/modebar-interactions-as-a-callback-property/86100 "2024-07-25T08:55:16Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![ksuryateja24](https://avatars.discourse-cdn.com/v4/letter/k/9f8e36/32.png) [@ksuryateja24](https://community.plotly.com/u/ksuryateja24)\
**Post date:** [July 25, 2024, 8:55am UTC](https://community.plotly.com/t/modebar-interactions-as-a-callback-property/86100/1 "2024-07-25T08:55:16Z")

</div>

Hi,

Is there a way to get the mode bar interactions like reset axis, pan… etc as the trigger to a callback

Thanks in advance

---

<div class="post-metadata">

**Author:** ![jinnyzor](https://sea2.discourse-cdn.com/flex024/user_avatar/community.plotly.com/jinnyzor/32/21194_2.png) [@jinnyzor](https://community.plotly.com/u/jinnyzor)\
**Post date:** [July 25, 2024, 11:56am UTC](https://community.plotly.com/t/modebar-interactions-as-a-callback-property/86100/2 "2024-07-25T11:56:51Z")

</div>

This is an interesting idea.

Interaction with the grid happens and relayout is called. You could add event listeners to when these buttons are pushed and use `dash_clienstide.set_props` to change any components props directly from there.

I believe that there may be a spot in the code where the mode of the cursor is changed which could be used for a prop. Things like the plotly link and image creation, I don’t think trigger this mode change. Would you also want to know when something is triggered for the link and image?

You could add an event listener to the whole div, as outlined here:

> <https://github.com/plotly/dash/issues/2928>
>
> Hi, hoping someone can help me here.
> 
> Here's a minimal version for the problem… I'm encountering. I'm developing an app that will have multiple plots (seismic traces) where a user needs to be able to add a vertical line for arrival times. I need to get actual mouse position in data coordinates, not nearest clickData.
> 
> I assign an EventListener to each plot when I dynamically create them. The code here doesn't work until I make a trivial edit/unedit and save again in debug mode - in which case it starts registering the alt-click and draws a dashed vertical line (see screen-shot).
> 
> Is the Graph initialization preventing the propagation of the click event, and then subsequent debug reloads capture it again? What can I do to make it work after Graph initialization, or am I using the wrong approach, or is this not possible in Dash?
> 
> Thanks for any help.
> 
> !\[click\_graph\](https://github.com/user-attachments/assets/ca9b2032-4311-4881-8cf7-66383ac1aa7b)
> \---
> 
> \`\`\`
> from dash import Dash, dcc, html, State, Input, Output, callback, no\_update, MATCH
> from dash.exceptions import PreventUpdate
> from dash\_extensions import EventListener
> import plotly.express as px
> 
> import numpy as np
> 
> click = {"event": "click", "props": \['srcElement.attributes.class.value', 'srcElement.height.animVal.value','srcElement.attributes.width.value','srcElement.attributes.x.value', 'srcElement.attributes.y.value', 'clientX', 'clientY','offsetX', 'offsetY', 'layerX', 'layerY', 'altKey', 'ctrlKey', 'shiftKey'\]}
> 
> app = Dash(\_\_name\_\_)
> df = px.data.tips()
> 
> app.layout = html.Div(\[
> html.Button('Plot', id='btn\_plot', n\_clicks=0), 
> html.Div(\[\], id='holder'),
> \])
> 
> @app.callback(
> Output('holder','children'),
> Input('btn\_plot','n\_clicks'),
> prevent\_initial\_call=True
> )
> def OnPlot(n\_clicks):
> evls = \[\]
> rx = np.arange(0.0,4\*np.pi,0.1)
> for i in range(2):
> x = rx\[(i+1)\*10:(i+1)\*10+100\]
> y = np.sin(x+i\*5)
> fig = px.scatter(x=x, y=y, range\_x = \[rx\[0\], rx\[-1\]\])
> fig.add\_vline(x=0.0, line\_dash="dot", line={'color':'grey', 'width': 0.75}, name='tP', opacity=0.0)
> graph = dcc.Graph(figure=fig, id={'type':'graph', 'value':i})
> evls.append(EventListener(graph, events=\[click\], logging=True, id={'type':'evl', 'value':i}))
> return evls
> 
> @app.callback(
> Output({'type':'graph', 'value':MATCH}, 'figure'),
> Input({'type':'evl', 'value':MATCH}, "n\_events"),
> State({'type':'evl', 'value':MATCH}, "event"),
> State({'type':'graph', 'value':MATCH}, 'figure'),
> State({'type':'graph', 'value':MATCH}, 'id'), prevent\_initial\_call=True 
> )
> def OnPlotClick(n\_events, e, figure, idGraph):
> if e is None:
> raise PreventUpdate()
> if not 'srcElement.attributes.class.value' in e:
> raise PreventUpdate() # outside plot area
> if e\['srcElement.attributes.class.value'\] != 'nsewdrag drag':
> raise PreventUpdate() # outside plot area
> if not e\['altKey'\]:
> raise PreventUpdate() # no alt key
> # calc x,y
> x\_min, x\_max = figure\['layout'\]\['xaxis'\]\['range'\]
> y\_min, y\_max = figure\['layout'\]\['yaxis'\]\['range'\]
> x\_rel = float(e\['offsetX'\]-int(e\['srcElement.attributes.x.value'\]))/float(e\['srcElement.attributes.width.value'\])
> y\_rel = 1.0-float(e\['offsetY'\]-int(e\['srcElement.attributes.y.value'\]))/float(e\['srcElement.height.animVal.value'\])
> x = x\_min + x\_rel\*(x\_max-x\_min)
> y = y\_min + y\_rel\*(y\_max-y\_min)
> print('Graph #: %d, x=%1.3f y=%1.3f' % (idGraph\['value'\], x, y))
> vline = shapes = figure\['layout'\]\['shapes'\]\[0\]
> vline\['x0'\] = x
> vline\['x1'\] = x
> vline\['opacity'\] = 1.0
> if (0.0 \<= x\_rel \<= 1.0) and (0.0 \<= y\_rel \<= 1.0):
> return figure
> else:
> return no\_update
> 
> 
> app.run(debug=True)
> \`\`\`

And use this to check which modebar button was pushed.

---

<div class="post-metadata">

**Author:** ![ksuryateja24](https://avatars.discourse-cdn.com/v4/letter/k/9f8e36/32.png) [@ksuryateja24](https://community.plotly.com/u/ksuryateja24)\
**Post date:** [July 25, 2024, 12:28pm UTC](https://community.plotly.com/t/modebar-interactions-as-a-callback-property/86100/3 "2024-07-25T12:28:09Z")

</div>

@jinnyzor  
So, there is no direct way like relayout data for the modebar buttons.  
and the work around is to have an event listerner.  
Is there any sample code which I can go through to do this.  
I just want to a function trigger on when reset axis is clicked in the Modebar

![image](https://us1.discourse-cdn.com/flex024/uploads/plot/original/3X/d/8/d8f7a29ddf97c2dcd21aa40e45bafebedf53b9e2.png)

also is the event listener available in all versions of dash?
