Personal memorandum.
--In the next product, we aim to be able to analyze data using matplotlib plots, but since it is a little inflexible, we would like to add a GUI so that Tkinter can operate graphs freely.
--Therefore, we will extend NavigationToolbar2TK, which is the default navigation toolbar.
disable_somebuttons.py
import matplotlib.pyplot as plt
import tkinter as tk
from matplotlib.backends.backend_tkagg import (FigureCanvasTkAgg, NavigationToolbar2Tk)
class NavigationToolbarExt(NavigationToolbar2Tk):
toolitems = [t for t in NavigationToolbar2Tk.toolitems if t[0] in ('Pan', 'Save')]
## ---abridgement--- ##
##Below is the main program###
root = tk.Tk()
fig = plt.figure(figsize=(8, 5))
canvas = FigureCanvasTkAgg(fig, master=root)
canvas.draw()
toolbar = NavigationToolbarExt(canvas, root)
canvas.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH, expand=1)
toolbar.pack(side=tk.BOTTOM, fill=tk.BOTH)
root.protocol("WM_DELETE_WINDOW", toolbar.quit)
root.mainloop()
Only Pan and Save will be displayed.
--Add a declaration statement related to self._buttons to the constructor.
――In addition, ToolTip will not work with this alone, so I will add a sentence about ToolTip.
--Currently, toggle = False, but there is a possibility that toggle = True can be supported by overriding another method. (Investigation required)
originalbutton.py
import matplotlib.pyplot as plt
import tkinter as tk
from matplotlib.backends.backend_tkagg import (FigureCanvasTkAgg, NavigationToolbar2Tk)
from matplotlib.backends._backend_tk import (ToolTip)
class NavigationToolbarExt(NavigationToolbar2Tk):
toolitems = [t for t in NavigationToolbar2Tk.toolitems if t[0] in ('Pan', 'Save')]
def __init__(self, canvas=None, master=None):
super().__init__(canvas, master)
# move2.With png as an icon, when that button is clicked, a member method called HelloWorld is executed.
#In addition, Foo as ToolTip?Is displayed.
self._buttons["Foo"] = (self._Button('Foo', 'move2.png', toggle=False , command=getattr(self, 'HelloWorld')))
ToolTip.createToolTip(self._buttons["Foo"], 'Foo?')
self.canvas = canvas
self.master = master
def HelloWorld(self):
print("HelloWorld")
### (Omitted below) ###
--Override press_pan
pan_somegraph.py
import matplotlib.pyplot as plt
import tkinter as tk
from matplotlib.backends.backend_tkagg import (FigureCanvasTkAgg, NavigationToolbar2Tk)
class NavigationToolbarExt(NavigationToolbar2Tk):
def press_pan(self, event):
if( event.inaxes != None): #When clicked outside the frame(event.inaxes==None)Want to ignore
if event.inaxes.get_subplotspec().colspan.start == 1: #Only the one specified as No. 1 is targeted
super().press_pan(event)
### (Omitted below) ###
--Override pan
--In C #, the delegate operator (+ =,-=) is often used to control whether or not an event can be accepted, but it was implemented using the same principle. The corresponding functions are mpl_connect and mpl_disconnect.
Note that if you don't put a button event in the constructor as well, the click of the first action will be ignored. The constructor is also light but needs to be implemented.
pan_click_available_onlyidle.py
import matplotlib.pyplot as plt
import tkinter as tk
from matplotlib.backends.backend_tkagg import (FigureCanvasTkAgg, NavigationToolbar2Tk)
from matplotlib.backend_bases import (_Mode)
class NavigationToolbarExt(NavigationToolbar2Tk):
toolitems = [t for t in NavigationToolbar2Tk.toolitems if t[0] in ('Pan', 'Save')]
def __init__(self, canvas=None, master=None):
super().__init__(canvas, master)
self.canvas = canvas
self.master = master
self.pressevent_cid = fig.canvas.mpl_connect('button_press_event', self.onclick) #Need here
def pan(self):
super().pan()
if self.mode == _Mode.PAN: #When in PAN mode
fig.canvas.mpl_disconnect(self.pressevent_cid) #Delete event
else: #If not in PAN mode
self.pressevent_cid = fig.canvas.mpl_connect('button_press_event', self.onclick) #Add an event
def onclick(self, event):
print("Clicked")
## (Omitted below) ###
When I made a pull request, I received another proposal. This may be the cleanest form. However, there are some concerns when setting a color other than the background color.
import matplotlib.pyplot as plt
import tkinter as tk
from matplotlib.backends.backend_tkagg import (FigureCanvasTkAgg, NavigationToolbar2Tk)
class NavigationToolbarExt(NavigationToolbar2Tk):
def __init__(self, canvas=None, master=None):
super().__init__(canvas, master)
self.canvas = canvas
self.master = master
self['bg'] = 'white'
for item in self.winfo_children():
item['bg'] = 'white'
Since tkinter is used, python.exe may not end unless the following syntax is added to the main routine, so be careful.
root.protocol("WM_DELETE_WINDOW", toolbar.quit)
Recommended Posts