I'm writing a script using tkinter and matplotlib for data processing, some parts of the code requires polygon selector to choose a region of interest. However, PolygonSelector fails to detect the motion of cursor.
It should be noted that this issue occurs when the interactive mode of matplotlib figure is on.
Simplified code and result are shown below:
#!/usr/bin/env python3
import matplotlib
matplotlib.use("TkAgg")
import tkinter as tk
import matplotlib.pyplot as plt
from matplotlib.widgets import PolygonSelector
root = tk.Tk()
def draw():
fig = plt.figure()
ax = fig.add_subplot(111)
plt.ion() # interactive mode is on
plt.show()
def onselect(data_input):
print(data_input)
PS = PolygonSelector(ax, onselect)
tk.Button(root, text='draw', command=draw).pack()
root.mainloop()
This is the plot after clicking 'draw' button on tkinter GUI, the starting point of polygon stucks at (0,0), it is expected to move with cursor:
When I call draw()
outside of tkinter, PolygonSelector works fine:
def draw():
fig = plt.figure()
ax = fig.add_subplot(111)
plt.ion() # interactive mode is on
plt.show()
def onselect(data_input):
print(data_input)
PS = PolygonSelector(ax, onselect)
a = input() # prevent window from closing when execution is done
draw()
The simple solution would be to make sure you make your Polygon Selector a global variable. This will keep the selector visually updating.
#!/usr/bin/env python3
import tkinter as tk
import matplotlib
import matplotlib.pyplot as plt
from matplotlib.widgets import PolygonSelector
matplotlib.use("TkAgg")
root = tk.Tk()
ps = None
def draw():
global ps
fig = plt.figure()
ax = fig.add_subplot(111)
plt.ion()
plt.show()
ps = PolygonSelector(ax, on_select)
def on_select(data_input):
print(data_input)
tk.Button(root, text='draw', command=draw).pack()
root.mainloop()
If you build this into a class then you can avoid the use of global and get the behavior you want by apply the Polygon Selector as a class attribute.
#!/usr/bin/env python3
import tkinter as tk
import matplotlib
import matplotlib.pyplot as plt
from matplotlib.widgets import PolygonSelector
matplotlib.use("TkAgg")
class GUI(tk.Tk):
def __init__(self):
super().__init__()
self.ps = None
tk.Button(self, text='draw', command=self.draw).pack()
def draw(self):
fig = plt.figure()
ax = fig.add_subplot(111)
plt.ion()
plt.show()
self.ps = PolygonSelector(ax, self.on_select)
def on_select(self, data_input):
print(data_input)
if __name__ == "__main__":
GUI().mainloop()
Results:
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.