ipympl icon indicating copy to clipboard operation
ipympl copied to clipboard

Make the toolbar customizable

Open nvaytet opened this issue 5 years ago • 14 comments

Hi, Is it possible to add custom buttons to the toolbar? Many thanks for any help.

nvaytet avatar Oct 08 '20 22:10 nvaytet

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

martinRenou avatar Oct 09 '20 06:10 martinRenou

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.

thomasaarholt avatar Oct 09 '20 06:10 thomasaarholt

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.

martinRenou avatar Oct 09 '20 07:10 martinRenou

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 Screenshot at 2020-10-09 08-58-30 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. Screenshot at 2020-10-09 09-04-33

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!

nvaytet avatar Oct 09 '20 07:10 nvaytet

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..)

nvaytet avatar Oct 09 '20 07:10 nvaytet

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 avatar Oct 09 '20 07:10 martinRenou

@martinRenou that's a great idea! I agree it's not super clean, but it's at least very simple and works: Screenshot at 2020-10-09 09-54-05 Thanks!

nvaytet avatar Oct 09 '20 07:10 nvaytet

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

ianhi avatar Oct 09 '20 19:10 ianhi

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.

nvaytet avatar Oct 09 '20 20:10 nvaytet

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 Screenshot at 2020-10-29 14-33-57

So in combination with my workaround above, i'm able to almost completely customize my toolbar.

nvaytet avatar Oct 29 '20 13:10 nvaytet

Yes indeed, I forgot about this :) This is actually Matplotlib API if I am correct.

martinRenou avatar Oct 29 '20 14:10 martinRenou

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...

nvaytet avatar Dec 02 '20 20:12 nvaytet