0

I am using matplotlib with tk/tkinter, following the "Embedding in Tk"

self._figure = Figure()
self._axes: matplotlib.axes.Axes = self._figure.add_subplot(111)
self._canvas = FigureCanvasTkAgg(self._figure, master=frame)

toolbar = NavigationToolbar2Tk(self._canvas, frame)
toolbar.update()

According to Tool Manager

self._figure.canvas.manager.toolmanager.remove_tool("pan")

should work, but it does not.

# self._figure.canvas does not have attribute 'manager'

As one can see in the screenshot from vs-code, FigureCanvasTkAgg does not have attribute 'manager':

enter image description here

How to remove the toolbar button?

Martin Meeser
  • 2,784
  • 2
  • 28
  • 41
  • why error say that `self._figure` doesn't have `manager` if `manager` should be in `self._figure.canvas`? Maybe you forgot `canvas` in `self._figure.canvas.manager` ? – furas Dec 03 '19 at 11:20
  • maybe try with `self._canvas.manager.toolmanager.remove_tool("pan")` – furas Dec 03 '19 at 11:24
  • thanks for the comments but that's only a slight mistake in the question, I corrected the q and added screenshot from debugger – Martin Meeser Dec 03 '19 at 11:26
  • `toolbar.children['!button4'].pack_forget()` - EDIT: correction from `'!button5'` to `'!button4'` – furas Dec 03 '19 at 11:32

1 Answers1

5

It seems Canvas and NavigationToolbar2Tk embedded in tkinter have different constructions and differen functions. Standard matplotlib window uses Qt as backend.


toolbar = NavigationToolbar2Tk(self._canvas, frame)

To list information about buttons

print(toolbar.toolitems)    

To remove Pan button - it is 4th button

toolbar.children['!button4'].pack_forget()

To assign new function to existing button - ie. Home

def my_function():
    print("Pressed Home")

toolbar.children['!button1'].config(command=my_function)

To add new button

button = tkinter.Button(master=toolbar, text="Quit", command=_quit)
#button.pack()
button.pack(side="left")

The same way you could add other tkinter widgets - Label, Entry, etc.


EDIT: as ImportanceOfBeingErnest mentioned in comment it can be done more elegant way.

NavigationToolbar2Tk.toolitems = [t for t in NavigationToolbar2Tk.toolitems if
             t[0] not in ('Pan',)]

Full working example

import tkinter

from matplotlib.backends.backend_tkagg import (
    FigureCanvasTkAgg, NavigationToolbar2Tk)
# Implement the default Matplotlib key bindings.
from matplotlib.backend_bases import key_press_handler
from matplotlib.figure import Figure

import numpy as np


root = tkinter.Tk()
root.wm_title("Embedding in Tk")

fig = Figure(figsize=(5, 4), dpi=100)
t = np.arange(0, 3, .01)
fig.add_subplot(111).plot(t, 2 * np.sin(2 * np.pi * t))

canvas = FigureCanvasTkAgg(fig, master=root)  # A tk.DrawingArea.
canvas.draw()
canvas.get_tk_widget().pack(side=tkinter.TOP, fill=tkinter.BOTH, expand=1)

# ---

NavigationToolbar2Tk.toolitems = [t for t in NavigationToolbar2Tk.toolitems if
                                  t[0] not in ('Pan',)]

# ---

toolbar = NavigationToolbar2Tk(canvas, root)
toolbar.update()

canvas.get_tk_widget().pack(side=tkinter.TOP, fill=tkinter.BOTH, expand=1)



print(toolbar.toolitems)

def on_key_press(event):
    print("you pressed {}".format(event.key))
    key_press_handler(event, canvas, toolbar)


canvas.mpl_connect("key_press_event", on_key_press)


def _quit():
    root.quit()     # stops mainloop
    root.destroy()  # this is necessary on Windows to prevent
                    # Fatal Python Error: PyEval_RestoreThread: NULL tstate


button = tkinter.Button(master=root, text="Quit", command=_quit)
button.pack(side=tkinter.BOTTOM)

tkinter.mainloop()
# If you put root.destroy() here, it will cause an error if the window is
# closed with the window manager.
furas
  • 134,197
  • 12
  • 106
  • 148
  • 3
    Rather than messing with the GUI itself, check existing answers at https://stackoverflow.com/questions/55779944/how-to-remove-toolbar-buttons-from-matplotlib or https://stackoverflow.com/questions/12695678/how-to-modify-the-navigation-toolbar-easily-in-a-matplotlib-figure-window – ImportanceOfBeingErnest Dec 03 '19 at 13:47
  • @ImportanceOfBeingErnest thank you for links. I suspected that changing `toolitems` may change buttons but I was to lazy to check it with code or search links. Simply my messing was shorter to write and faster to test ;) – furas Dec 03 '19 at 15:37
  • I added full working example with solutions which suggested @ImportanceOfBeingErnest – furas Dec 03 '19 at 15:55