Make the toolbar customizable
Hi, Is it possible to add custom buttons to the toolbar? Many thanks for any help.
Hi,
It's not possible, although you could definitely use ipywidgets and create a Button and a container for both your button and your plot
This is something that would be quite nice to add - if it isn't that hard. We were talking about it over at the hyperspy repo in the last year.
It might not be too difficult I guess.
We could actually redesign the current Toolbar as being a bunch of ipywidgets Buttons in a VBox, so that it's easier remove buttons or add new ones in Python.
Hi,
It's not possible, although you could definitely use ipywidgets and create a Button and a container for both your button and your plot
Thanks.
I have managed to create a button, and put the toolbar and the button inside a VBox.
import matplotlib.pyplot as plt
import ipywidgets as ipw
fig, ax = plt.subplots()
new_toolbar = ipw.VBox([fig.canvas.toolbar, ipw.Button(icon='exchange', layout={"width": "34px"})])
new_toolbar
which gives me
So when I use the folding button, my new button is still there, but that's no big deal for me as I hardly ever use the fold button anyway.

Now my question is how can I display the new_toolbar, next to the plot?
I was trying to put the new_toolbar and the plot inside a HBox but i can't seem to get the plot only (without the toolbar) as a widget. Any pointers?
Thanks!
It might not be too difficult I guess.
We could actually redesign the current Toolbar as being a bunch of ipywidgets Buttons in a VBox, so that it's easier remove buttons or add new ones in Python.
That would be really nice! Would make it super easy to customize, and maybe rearrange (move buttons around into different containers, etc..)
Now my question is how can I display the new_toolbar, next to the plot? I was trying to put the new_toolbar and the plot inside a HBox but i can't seem to get the plot only (without the toolbar) as a widget. Any pointers?
There might not be a clean way of doing it in the current state of ipympl. But you might be able to hack around it by setting the plot's canvas.toolbar_visible flag to False, then put your extended toolbar inside an HBox with your plot.
@martinRenou that's a great idea!
I agree it's not super clean, but it's at least very simple and works:
Thanks!
We could actually redesign the current Toolbar as being a bunch of ipywidgets Buttons in a VBox, so that it's easier remove buttons or add new ones in Python.
:+1: to this. It also may make sense to keep in mind that matplotlib does have methods for modifying the toolbar. https://matplotlib.org/3.3.0/gallery/user_interfaces/toolmanager_sgskip.html
Yes I tried those methods but the functionality is not available with ipympl. The api is not exactly the same. And using the ipywidgets api seems much cleaner and makes more sense when the canvas is itself a widget.
In case you want to remove buttons from the toolbar, it seems that you can do this by changing the list of toolitems:
import matplotlib.pyplot as plt
%matplotlib widget
fig, ax = plt.subplots()
items = fig.canvas.toolbar.toolitems
new_tools = [items[0], items[3], items[4], items[5]]
fig.canvas.toolbar.toolitems = new_tools
fig.canvas
yields

So in combination with my workaround above, i'm able to almost completely customize my toolbar.
Yes indeed, I forgot about this :) This is actually Matplotlib API if I am correct.
In addition, I have another workaround if you wish to customize either the appearance of the buttons in the original mpl toolbar, or their behaviour.
I can replace them with custom icons by just hiding the toolbar entirely, and add for example a custom "Home" button with any icon I want, and inside my callback I can call the original matplotlib fig.canvas.toolbar.home() function, and any other additional methods of my choosing.
The other methods are zoom(), pan(), save_figure() etc...