# modeBar add custom button using python

**URL:** <https://community.plotly.com/t/modebar-add-custom-button-using-python/70567>\
**Category:** Dash Python\
**Tags:** question\
**Created:** [December 6, 2022, 11:15am UTC](https://community.plotly.com/t/modebar-add-custom-button-using-python/70567 "2022-12-06T11:15:22Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![surr2025](https://avatars.discourse-cdn.com/v4/letter/s/57b2e6/32.png) [@surr2025](https://community.plotly.com/u/surr2025)\
**Post date:** [December 6, 2022, 11:15am UTC](https://community.plotly.com/t/modebar-add-custom-button-using-python/70567/1 "2022-12-06T11:15:22Z")

</div>

Hi,

I need to add button in modeBarAddButton ie custom buttom in Modebar config field using python.

Thanks

---

<div class="post-metadata">

**Author:** ![AIMPED](https://sea2.discourse-cdn.com/flex024/user_avatar/community.plotly.com/aimped/32/21758_2.png) [@AIMPED](https://community.plotly.com/u/AIMPED)\
**Post date:** [December 6, 2022, 11:31am UTC](https://community.plotly.com/t/modebar-add-custom-button-using-python/70567/2 "2022-12-06T11:31:57Z")

</div>

Hi @surr2025 welcome to the forums.

Up to my knowledge this not possible.

Forum search:

> [@Python Plotly - Add customised button to ModeBar](https://community.plotly.com/t/python-plotly-add-customised-button-to-modebar/69584):
>
> In Javascript plotly [one can add](https://plotly.com/javascript/configuration-options/#add-buttons-to-modebar) customised buttons to Plotly’s ModeBar. See for example this [pen](https://codepen.io/rhamner/pen/WaazPz). The same seems to be [possible in R](https://plotly-r.com/control-modebar.html). How does one do this in Python? A minimal example of how I would expect this to work is import plotly.graph\_objects as go import plotly.io as pio pio.renderers.default = "browser" fig = go.Figure() fig.add\_trace(go.Scatter(x=[1, 2, 3], y=[1, 3, 1])) fig.show(config=dict({'displaylogo': True, 'scrollZoom': True,…

---

<div class="post-metadata">

**Author:** ![surr2025](https://avatars.discourse-cdn.com/v4/letter/s/57b2e6/32.png) [@surr2025](https://community.plotly.com/u/surr2025)\
**Post date:** [December 6, 2022, 11:40am UTC](https://community.plotly.com/t/modebar-add-custom-button-using-python/70567/3 "2022-12-06T11:40:21Z")

</div>

Thanks for the quick response.

What if I created Javascript function which will search the modebar and add/append img to it at last.  
Then created a hidden button {‘display’:‘none’} and mapped this button id with the button id mention in Javascript function.

I need to call this function once the graph is fully loaded.

How can I call Javascript function (present in html file where plotly app\_id is specified) from dash-python?

---

<div class="post-metadata">

**Author:** ![AIMPED](https://sea2.discourse-cdn.com/flex024/user_avatar/community.plotly.com/aimped/32/21758_2.png) [@AIMPED](https://community.plotly.com/u/AIMPED)\
**Post date:** [December 6, 2022, 11:43am UTC](https://community.plotly.com/t/modebar-add-custom-button-using-python/70567/4 "2022-12-06T11:43:36Z")

</div>

I don’t know much about JS, but this should be possible. Cientside callbacks for example are written in JS. Have you used the forum search. I am pretty sure that this has been asked before.

---

<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:** [December 6, 2022, 12:17pm UTC](https://community.plotly.com/t/modebar-add-custom-button-using-python/70567/5 "2022-12-06T12:17:10Z")

</div>

Hello @surr2025,

Yes, you can create a custom modebar button via JavaScript.

I use it in my own stuff every now and then.

The easiest way to add it is to use a clientside\_callback to trigger it with a settimeout of about 300. You can give it the same class as the other buttons to get some of the same effects as the other buttons.

One nice way to call it is:

```auto
app.clientside_callback(
‘’’function to add the button here’’’,
Output(‘mygraph’,’id’),
Input(‘mygraph’,’id’)
)

```

Two important things, do not prevent\_initial\_call and on the clientside\_callback. You need to return `window.dash_clientside.no_update`

Let me know if you need more info, but I think you can figure it out from here.

---

<div class="post-metadata">

**Author:** ![surr2025](https://avatars.discourse-cdn.com/v4/letter/s/57b2e6/32.png) [@surr2025](https://community.plotly.com/u/surr2025)\
**Post date:** [December 6, 2022, 3:11pm UTC](https://community.plotly.com/t/modebar-add-custom-button-using-python/70567/6 "2022-12-06T15:11:33Z")

</div>

setimeout will execute every 300ms. Can we call JavaScript function only once… After dcc.loading loads all the graph?

---

<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:** [December 6, 2022, 3:13pm UTC](https://community.plotly.com/t/modebar-add-custom-button-using-python/70567/7 "2022-12-06T15:13:10Z")

</div>

No, setTimeout says that you want to wait on the execution of the function for 300ms.

What you are thinking of is setinterval.

---

<div class="post-metadata">

**Author:** ![surr2025](https://avatars.discourse-cdn.com/v4/letter/s/57b2e6/32.png) [@surr2025](https://community.plotly.com/u/surr2025)\
**Post date:** [December 6, 2022, 3:20pm UTC](https://community.plotly.com/t/modebar-add-custom-button-using-python/70567/8 "2022-12-06T15:20:36Z")

</div>

I was using graph under children component of dcc.loading…

Once the graph is loaded completely then only I want to call JavaScript function to add custom button to modebar.

The custom button can be added only after the graph is loaded.

Set interval 300ms results calling of JavaScript function after 300ms.

How can I wait to check whether graph is loaded?  
By using loading\_state or something else?

---

<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:** [December 6, 2022, 3:22pm UTC](https://community.plotly.com/t/modebar-add-custom-button-using-python/70567/9 "2022-12-06T15:22:49Z")

</div>

you should be using _ **setTimeout** _

setTimeout delays the function call for 300ms.

---

<div class="post-metadata">

**Author:** ![surr2025](https://avatars.discourse-cdn.com/v4/letter/s/57b2e6/32.png) [@surr2025](https://community.plotly.com/u/surr2025)\
**Post date:** [December 6, 2022, 3:27pm UTC](https://community.plotly.com/t/modebar-add-custom-button-using-python/70567/10 "2022-12-06T15:27:10Z")

</div>

Is it not possible using loading\_state… to check whether graph is loaded or not?

---

<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:** [December 6, 2022, 3:32pm UTC](https://community.plotly.com/t/modebar-add-custom-button-using-python/70567/11 "2022-12-06T15:32:56Z")

</div>

Can you please post what you are trying for the clientside\_callback? Including how to trigger it?

---

<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:** [December 6, 2022, 3:43pm UTC](https://community.plotly.com/t/modebar-add-custom-button-using-python/70567/12 "2022-12-06T15:43:41Z")

</div>

And as far as whether or not it is loading, you can try checking out here:

> **[Graph | Dash for Python Documentation | Plotly](https://dash.plotly.com/dash-core-components/graph)**
>
> Graph

---

<div class="post-metadata">

**Author:** ![surr2025](https://avatars.discourse-cdn.com/v4/letter/s/57b2e6/32.png) [@surr2025](https://community.plotly.com/u/surr2025)\
**Post date:** [December 7, 2022, 5:10am UTC](https://community.plotly.com/t/modebar-add-custom-button-using-python/70567/13 "2022-12-07T05:10:20Z")

</div>

Thanks for the update…

Please checkout below code for your reference.

```auto
app.layout = html.Div([
		       dbc.Row([
                    		dcc.Loading(
                        	id="loading",
                        	type="circle",
                       		children= [dcc.Graph(id='graph_id')],
                       		)
        		]),
			 dbc.Button("modebar_button", id="modebar_button", n_clicks=0, style={'display':'none'}),
		    ])

# clientside_callback
app.clientside_callback(
    """
        function add_button_modebar() {
	# javascript code to add button in modebar.
	# id="modebar_button", 
	# onclick event
	# This function needs to call automatically once graph is loaded completely ie id="loading"
	}
    """
    Output('no_output', 'no_output'),
    Input('memory', 'data'),
)

```

---

<div class="post-metadata">

**Author:** ![surr2025](https://avatars.discourse-cdn.com/v4/letter/s/57b2e6/32.png) [@surr2025](https://community.plotly.com/u/surr2025)\
**Post date:** [December 7, 2022, 9:22am UTC](https://community.plotly.com/t/modebar-add-custom-button-using-python/70567/14 "2022-12-07T09:22:29Z")

</div>

Hi,

_ **setTimeout** _ not working. In my case function got called automatically.

It will not wait to load the graph.

Due to the instant function call, modebar div ie doc.querySelector(“div.modebar-container div”) can’t detected by using javascript function.

Would you please provide sample code to check whether graph is loaded or not? I will pass this parameter to the javascript function.

---

<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:** [December 7, 2022, 9:23am UTC](https://community.plotly.com/t/modebar-add-custom-button-using-python/70567/15 "2022-12-07T09:23:39Z")

</div>

How are you using setTimeout, can you post your callback?

---

<div class="post-metadata">

**Author:** ![surr2025](https://avatars.discourse-cdn.com/v4/letter/s/57b2e6/32.png) [@surr2025](https://community.plotly.com/u/surr2025)\
**Post date:** [December 7, 2022, 9:27am UTC](https://community.plotly.com/t/modebar-add-custom-button-using-python/70567/16 "2022-12-07T09:27:22Z")

</div>

```auto
app.clientside_callback(
    """
        setTimeout(myFunction, 300);

        function myFunction() {
            console.log("Function called")
            doc = window.frames[0].document
            d = doc.querySelector("div.modebar-container div");
            # remaining code to add img button + onClick
        }
    Output('display', 'value'),
    Input('memory', 'data'),

```

---

<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:** [December 7, 2022, 9:29am UTC](https://community.plotly.com/t/modebar-add-custom-button-using-python/70567/17 "2022-12-07T09:29:37Z")

</div>

Ok, for setTimeout you need to try this:

```auto
SetTimeout(function(){myfunction()},300)

```

Also, any console errors from it not knowing the function at time of call?

---

<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:** [December 7, 2022, 9:33am UTC](https://community.plotly.com/t/modebar-add-custom-button-using-python/70567/18 "2022-12-07T09:33:19Z")

</div>

Also, your callbacks need to always return something.

---

<div class="post-metadata">

**Author:** ![surr2025](https://avatars.discourse-cdn.com/v4/letter/s/57b2e6/32.png) [@surr2025](https://community.plotly.com/u/surr2025)\
**Post date:** [December 7, 2022, 9:34am UTC](https://community.plotly.com/t/modebar-add-custom-button-using-python/70567/19 "2022-12-07T09:34:42Z")

</div>

Hi Tested above code also.

same error.  
`Uncaught TypeError: Cannot read properties of undefined (reading 'document') `  
Function get executed before graph loaded that why not getting ‘documment’ → Uncaughterror .

---

<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:** [December 7, 2022, 9:37am UTC](https://community.plotly.com/t/modebar-add-custom-button-using-python/70567/20 "2022-12-07T09:37:18Z")

</div>

Your graph is getting displayed in a iframe?

You need to trigger this upon the id of the graph itself and not memory data.

[Next page](https://community.plotly.com/t/modebar-add-custom-button-using-python/70567.md?page=2)
