我正在制作一个GUI(到目前为止)可以在图形上绘制多个矩形,检索这些矩形的坐标,然后将这些坐标写入可以保存为.txt文件的列表。 我希望能够删除我不需要的任何矩形,并从图中和list / txt文件中删除它们。到目前为止,我能够删除最后绘制的补丁(仅从图中删除它,而不是列表),但是当我再次点击时我得到错误:
Traceback (most recent call last):
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/lib-tk/Tkinter.py", line 1536, in __call__
return self.func(*args)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/matplotlib/backends/backend_tkagg.py", line 395, in button_press_event
FigureCanvasBase.button_press_event(self, x, y, num, dblclick=dblclick, guiEvent=event)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/matplotlib/backend_bases.py", line 1785, in button_press_event
self.callbacks.process(s, mouseevent)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/matplotlib/cbook.py", line 527, in process
proxy(*args, **kwargs)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/matplotlib/cbook.py", line 405, in __call__
return mtd(*args, **kwargs)
File "stack_overflowquestion.py", line 115, in delete_click
self.rect.remove()
File "/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/matplotlib/artist.py", line 135, in remove
self._remove_method(self)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/matplotlib/axes.py", line 1564, in <lambda>
p._remove_method = lambda h: self.patches.remove(h)
ValueError: list.remove(x): x not in list
我希望能够点击任何矩形并将其删除,而不是按照绘制顺序删除它们。我想这意味着我需要在创建矩形时以某种方式命名/索引矩形。
我的代码:
import numpy as np
import matplotlib
matplotlib.use('TkAgg')
from matplotlib.figure import *
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2TkAgg
import matplotlib.pyplot as plt
from matplotlib import gridspec
from matplotlib.ticker import MultipleLocator, FormatStrFormatter
import tkFileDialog
import tkMessageBox
import Tkinter as tk
from matplotlib.patches import Rectangle
Area = []
class simpleapp_tk(tk.Tk):
def __init__(self, parent):
tk.Tk.__init__(self, parent)
self.parent=parent
self.initialize()
def initialize(self):
button = tk.Button(self, text="Plot data", command=self.plot)
button.pack()
button = tk.Button(self, text="Quit", command=self.quit)
button.pack()
button = tk.Button(self, text="Save file", command=self.save)
button.pack()
self.labelVariable = tk.StringVar()
self.var = tk.IntVar()
label = tk.Label(self, textvariable=self.labelVariable, anchor = "w", fg = 'white', bg = 'blue')
label.pack()
self.labelVariable.set("Data Browser")
self.resizable(True, True)
def plot (self):
try:
self.fig = plt.figure('Input para+perp ATB')
gs = gridspec.GridSpec(4, 6)
self.ax1 = self.fig.add_subplot(gs[0:4, 0:5])
im = self.ax1.plot([1, 2, 3, 4, 5, 6, 7], [2, 4, 6, 8, 9, 11, 12])
canvas = FigureCanvasTkAgg(self.fig, master=self)
canvas.show()
canvas.get_tk_widget().pack()
toolbar = NavigationToolbar2TkAgg(canvas, self)
toolbar.update()
canvas._tkcanvas.pack(side=tk.TOP, fill=tk.BOTH, expand=True)
aid = self.fig.canvas.mpl_connect('button_press_event', self.on_press)
bid = self.fig.canvas.mpl_connect('button_release_event', self.on_release)
cid = self.fig.canvas.mpl_connect('motion_notify_event', self.on_motion)
did = self.fig.canvas.mpl_connect('button_press_event', self.delete_click)
Radio1 = tk.Radiobutton(text = 'Select areas', variable = self.var, indicatoron=0, value = 1)
Radio2 = tk.Radiobutton(text = 'Delete areas', variable = self.var, indicatoron=0, value = 2)
Radio1.pack()
Radio2.pack()
except SyntaxError:
tkMessageBox.showinfo("No file selected", "Please select a file")
def on_press(self, event):
self.is_pressed = True
if event.xdata is not None and event.ydata is not None:
if self.var.get() ==1:
self.rect = Rectangle((0, 0), 0, 0)
self.ax1.add_patch(self.rect)
self.x0, self.y0 = event.xdata, event.ydata
self.rect.set_width(0)
self.rect.set_height(0)
self.rect.set_xy((self.x0, self.y0))
self.fig.canvas.draw()
self.rect.set_edgecolor('red')
self.rect.set_linestyle('solid')
self.rect.set_facecolor('none')
self.rect.set_linewidth('5')
def on_motion(self, event):
try:
if self.is_pressed:
if event.xdata is not None and event.ydata is not None:
if self.var.get() ==1:
self.x1, self.y1 = event.xdata, event.ydata
self.rect.set_width(self.x1 - self.x0)
self.rect.set_height(self.y1 - self.y0)
self.rect.set_xy((self.x0, self.y0))
self.fig.canvas.draw()
except SyntaxError:
pass
def on_release(self, event):
self.is_pressed = False
if self.var.get() ==1:
self.x1, self.y1 = event.xdata, event.ydata
self.rect.set_xy((self.x0, self.y0))
print 'rect:', self.x0, self.y0, self.x1, self.y1
coords =([self.x0, self.y0, self.x1, self.y1])
Area.append(coords)
self.fig.canvas.draw()
def delete_click(self, event):
self.is_pressed = True
if self.var.get() ==2:
self.rect.remove()
def save(self):
file = tkFileDialog.asksaveasfile(mode ='w', defaultextension=".txt")
if file is None:
return
savewhat = Area
for item in Area:
file.write("%s\n" % item)
file.close()
def quit():
root.destroy()
if __name__ == "__main__":
app = simpleapp_tk(None)
app.title('Data Browser')
app.mainloop()