Python Matplotlib事件和replotting
我希望能够创建一个绘图,根据绘图显示的内容按下一个按钮或另一个按钮,然后绘制以下对象。然而,我遇到了一些麻烦:似乎我不能让它“等待”直到按下按钮。另外,我想知道是否可以将一些参数传递给press_事件,比如保存某些内容的路径 这是该计划的方案,以防有所帮助。提前多谢Python Matplotlib事件和replotting,python,matplotlib,Python,Matplotlib,我希望能够创建一个绘图,根据绘图显示的内容按下一个按钮或另一个按钮,然后绘制以下对象。然而,我遇到了一些麻烦:似乎我不能让它“等待”直到按下按钮。另外,我想知道是否可以将一些参数传递给press_事件,比如保存某些内容的路径 这是该计划的方案,以防有所帮助。提前多谢 # event definition def ontype(event): if event.key == '1': do stuff 1 plt.savefig(...) p
# event definition
def ontype(event):
if event.key == '1':
do stuff 1
plt.savefig(...)
plt.clf()
elif event.key == '2':
do stuff 2
plt.savefig(...)
plt.clf()
elif event.key == '3':
do stuff 3
plt.savefig(...)
plt.clf()
# main program
...stuff
create figure
plt.show()
plt.gcf().canvas.mpl_connect('key_press_event',ontype)
在
plt.show()之前,必须调用plt.gcf().canvas.mpl\u connect('key\u press\u event',ontype)
。在非交互模式下,执行将在plt.show()
处等待,直到绘图窗口关闭
import pylab as plt
# event definition
def ontype(event):
if event.key == '1':
print "1"
elif event.key == '2':
print "2"
elif event.key == '3':
print "3"
# main program
plt.plot([1,6,3,8,7])
plt.gcf().canvas.mpl_connect('key_press_event',ontype)
plt.show()
或者,将示例中的plt.show()
替换为plt.ion()
,以启用交互模式。但这取决于您的具体需求,您更喜欢哪种解决方案
编辑
使用Tkinter的新示例
import random
import matplotlib
matplotlib.use('TkAgg')
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2TkAgg
from matplotlib.figure import Figure
try:
import Tkinter as Tk
except ImportError:
import tkinter as Tk
import tkMessageBox
class PlotClassifier(Tk.Tk):
def __init__(self, plot_generator, arguments, classes, classification_callback, *args, **kwargs):
Tk.Tk.__init__(self, *args, **kwargs)
self.title("Plot classifier, working on %i plots" % len(arguments))
#self.label = Tk.Label(text="Plot classifier, working on %i plots" % len(arguments))
#self.label.pack(padx=10, pady=10)
self._plot_generator = plot_generator
self._arguments = arguments
self._classes = [str(x) for x in classes]
self._classification_callback = classification_callback
self._setup_gui()
def _setup_gui(self):
#self.columnconfigure(0, minsize=100, weight=2)
#self.columnconfigure(1, minsize=500, weight=8)
f = Figure()
self._ax = f.add_subplot(111)
buttons_frame = Tk.Frame(self)
buttons_frame.pack(side=Tk.TOP, fill=Tk.BOTH, expand=True)
buttons_class = []
for i, cls in enumerate(self._classes):
buttons_class.append(Tk.Button(master=buttons_frame, text=cls,
command=lambda x=i: self.button_classification_callback(self._current_args, x)))
buttons_class[-1].pack(side=Tk.LEFT)
button_quit = Tk.Button(master=buttons_frame, text='Quit', command=self.destroy)
button_quit.pack(side=Tk.RIGHT) #.grid(row=0,column=0)
self._canvas = FigureCanvasTkAgg(f, master=self)
self._canvas.get_tk_widget().pack(side=Tk.TOP, fill=Tk.BOTH, expand=1) #.grid(row=0, column=1, rowspan=3) #
self._canvas.show()
toolbar = NavigationToolbar2TkAgg( self._canvas, self )
toolbar.pack(side=Tk.TOP, fill=Tk.BOTH, expand=1) #.grid(row=3, column=1) #
toolbar.update()
def button_classification_callback(self, args, class_idx):
self._classification_callback(args, self._classes[class_idx])
self.classify_next_plot()
def classify_next_plot(self):
try:
self._current_args = self._arguments.pop(0)
self._ax.cla()
self._plot_generator(self._ax, *self._current_args)
self._canvas.draw()
except IndexError:
tkMessageBox.showinfo("Complete!", "All plots were classified")
self.destroy()
def create_plot(ax, factor):
ax.plot([(i*factor) % 11 for i in range(100)])
def announce_classification(arguments, class_):
print arguments, class_
if __name__ == "__main__":
classes = ["Class %i"%i for i in range(1, 6)]
arguments_for_plot = [[random.randint(1,10)] for x in range(10)]
root = PlotClassifier(create_plot, arguments_for_plot, classes, classification_callback=announce_classification)
root.after(50, root.classify_next_plot)
root.mainloop()
该类将以下内容作为参数:
*创建每个绘图的回调
*要生成的每个绘图的参数列表(可能每个都是空列表)
*类名列表。为每个类创建一个按钮
*每次执行分类时调用的回调
如有任何反馈,将不胜感激
*编辑2*
请发表评论,这是一个稍加修改的版本。对于循环的每次迭代,都会打开一个新窗口
import random
import matplotlib
matplotlib.use('TkAgg')
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2TkAgg
from matplotlib.figure import Figure
try:
import Tkinter as Tk
except ImportError:
import tkinter as Tk
import tkMessageBox
class PlotClassifier(Tk.Tk):
def __init__(self, plot_generator, arguments, classes, *args, **kwargs):
Tk.Tk.__init__(self, *args, **kwargs)
self.title("Plot classifier")
self._plot_generator = plot_generator
self._arguments = arguments
self._classes = [str(x) for x in classes]
self.class_ = None
self._setup_gui()
def _setup_gui(self):
#self.columnconfigure(0, minsize=100, weight=2)
#self.columnconfigure(1, minsize=500, weight=8)
f = Figure()
self._ax = f.add_subplot(111)
buttons_frame = Tk.Frame(self)
buttons_frame.pack(side=Tk.TOP, fill=Tk.X, expand=True)
buttons_class = []
for i, cls in enumerate(self._classes):
buttons_class.append(Tk.Button(master=buttons_frame, text=cls,
command=lambda x=i: self.button_classification_callback(x)))
buttons_class[-1].pack(side=Tk.LEFT)
button_quit = Tk.Button(master=buttons_frame, text='Quit', command=self.destroy)
button_quit.pack(side=Tk.RIGHT) #.grid(row=0,column=0)
self._canvas = FigureCanvasTkAgg(f, master=self)
self._canvas.get_tk_widget().pack(side=Tk.TOP, fill=Tk.BOTH, expand=1) #.grid(row=0, column=1, rowspan=3) #
self._canvas.show()
toolbar = NavigationToolbar2TkAgg( self._canvas, self )
toolbar.pack(side=Tk.TOP, fill=Tk.BOTH, expand=1) #.grid(row=3, column=1) #
toolbar.update()
def button_classification_callback(self, class_idx):
self.class_ = self._classes[class_idx]
self.destroy()
def classify_plot(self):
self._ax.cla()
self._plot_generator(self._ax, *self._arguments)
self._canvas.draw()
self.mainloop()
return self.class_
def create_plot(ax, factor):
ax.plot([(i*factor) % 11 for i in range(100)])
if __name__ == "__main__":
classes = ["Class %i"%i for i in range(1, 6)]
arguments_for_plot = [[random.randint(1,10)] for x in range(10)]
for args in arguments_for_plot:
classifier = PlotClassifier(create_plot, args, classes)
class_ = classifier.classify_plot()
print args, class_
if class_ is None:
break
这有助于适应您自己的for循环,但您仍然必须在创建GUI后提供一个函数来进行绘图。您必须在plt.show()之前调用plt.gcf().canvas.mpl\u connect('key\u press\u event',ontype')
。在非交互模式下,执行将在plt.show()
处等待,直到绘图窗口关闭
import pylab as plt
# event definition
def ontype(event):
if event.key == '1':
print "1"
elif event.key == '2':
print "2"
elif event.key == '3':
print "3"
# main program
plt.plot([1,6,3,8,7])
plt.gcf().canvas.mpl_connect('key_press_event',ontype)
plt.show()
或者,将示例中的plt.show()
替换为plt.ion()
,以启用交互模式。但这取决于您的具体需求,您更喜欢哪种解决方案
编辑
使用Tkinter的新示例
import random
import matplotlib
matplotlib.use('TkAgg')
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2TkAgg
from matplotlib.figure import Figure
try:
import Tkinter as Tk
except ImportError:
import tkinter as Tk
import tkMessageBox
class PlotClassifier(Tk.Tk):
def __init__(self, plot_generator, arguments, classes, classification_callback, *args, **kwargs):
Tk.Tk.__init__(self, *args, **kwargs)
self.title("Plot classifier, working on %i plots" % len(arguments))
#self.label = Tk.Label(text="Plot classifier, working on %i plots" % len(arguments))
#self.label.pack(padx=10, pady=10)
self._plot_generator = plot_generator
self._arguments = arguments
self._classes = [str(x) for x in classes]
self._classification_callback = classification_callback
self._setup_gui()
def _setup_gui(self):
#self.columnconfigure(0, minsize=100, weight=2)
#self.columnconfigure(1, minsize=500, weight=8)
f = Figure()
self._ax = f.add_subplot(111)
buttons_frame = Tk.Frame(self)
buttons_frame.pack(side=Tk.TOP, fill=Tk.BOTH, expand=True)
buttons_class = []
for i, cls in enumerate(self._classes):
buttons_class.append(Tk.Button(master=buttons_frame, text=cls,
command=lambda x=i: self.button_classification_callback(self._current_args, x)))
buttons_class[-1].pack(side=Tk.LEFT)
button_quit = Tk.Button(master=buttons_frame, text='Quit', command=self.destroy)
button_quit.pack(side=Tk.RIGHT) #.grid(row=0,column=0)
self._canvas = FigureCanvasTkAgg(f, master=self)
self._canvas.get_tk_widget().pack(side=Tk.TOP, fill=Tk.BOTH, expand=1) #.grid(row=0, column=1, rowspan=3) #
self._canvas.show()
toolbar = NavigationToolbar2TkAgg( self._canvas, self )
toolbar.pack(side=Tk.TOP, fill=Tk.BOTH, expand=1) #.grid(row=3, column=1) #
toolbar.update()
def button_classification_callback(self, args, class_idx):
self._classification_callback(args, self._classes[class_idx])
self.classify_next_plot()
def classify_next_plot(self):
try:
self._current_args = self._arguments.pop(0)
self._ax.cla()
self._plot_generator(self._ax, *self._current_args)
self._canvas.draw()
except IndexError:
tkMessageBox.showinfo("Complete!", "All plots were classified")
self.destroy()
def create_plot(ax, factor):
ax.plot([(i*factor) % 11 for i in range(100)])
def announce_classification(arguments, class_):
print arguments, class_
if __name__ == "__main__":
classes = ["Class %i"%i for i in range(1, 6)]
arguments_for_plot = [[random.randint(1,10)] for x in range(10)]
root = PlotClassifier(create_plot, arguments_for_plot, classes, classification_callback=announce_classification)
root.after(50, root.classify_next_plot)
root.mainloop()
该类将以下内容作为参数:
*创建每个绘图的回调
*要生成的每个绘图的参数列表(可能每个都是空列表)
*类名列表。为每个类创建一个按钮
*每次执行分类时调用的回调
如有任何反馈,将不胜感激
*编辑2*
请发表评论,这是一个稍加修改的版本。对于循环的每次迭代,都会打开一个新窗口
import random
import matplotlib
matplotlib.use('TkAgg')
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2TkAgg
from matplotlib.figure import Figure
try:
import Tkinter as Tk
except ImportError:
import tkinter as Tk
import tkMessageBox
class PlotClassifier(Tk.Tk):
def __init__(self, plot_generator, arguments, classes, *args, **kwargs):
Tk.Tk.__init__(self, *args, **kwargs)
self.title("Plot classifier")
self._plot_generator = plot_generator
self._arguments = arguments
self._classes = [str(x) for x in classes]
self.class_ = None
self._setup_gui()
def _setup_gui(self):
#self.columnconfigure(0, minsize=100, weight=2)
#self.columnconfigure(1, minsize=500, weight=8)
f = Figure()
self._ax = f.add_subplot(111)
buttons_frame = Tk.Frame(self)
buttons_frame.pack(side=Tk.TOP, fill=Tk.X, expand=True)
buttons_class = []
for i, cls in enumerate(self._classes):
buttons_class.append(Tk.Button(master=buttons_frame, text=cls,
command=lambda x=i: self.button_classification_callback(x)))
buttons_class[-1].pack(side=Tk.LEFT)
button_quit = Tk.Button(master=buttons_frame, text='Quit', command=self.destroy)
button_quit.pack(side=Tk.RIGHT) #.grid(row=0,column=0)
self._canvas = FigureCanvasTkAgg(f, master=self)
self._canvas.get_tk_widget().pack(side=Tk.TOP, fill=Tk.BOTH, expand=1) #.grid(row=0, column=1, rowspan=3) #
self._canvas.show()
toolbar = NavigationToolbar2TkAgg( self._canvas, self )
toolbar.pack(side=Tk.TOP, fill=Tk.BOTH, expand=1) #.grid(row=3, column=1) #
toolbar.update()
def button_classification_callback(self, class_idx):
self.class_ = self._classes[class_idx]
self.destroy()
def classify_plot(self):
self._ax.cla()
self._plot_generator(self._ax, *self._arguments)
self._canvas.draw()
self.mainloop()
return self.class_
def create_plot(ax, factor):
ax.plot([(i*factor) % 11 for i in range(100)])
if __name__ == "__main__":
classes = ["Class %i"%i for i in range(1, 6)]
arguments_for_plot = [[random.randint(1,10)] for x in range(10)]
for args in arguments_for_plot:
classifier = PlotClassifier(create_plot, args, classes)
class_ = classifier.classify_plot()
print args, class_
if class_ is None:
break
这有助于适应您自己的for循环,但在创建GUI后,您仍然必须提供一个函数来进行绘图。Hm…我仍然对事件有问题。这个想法是对大量的情节进行分析,并根据不同类型的情节进行分类。这就是按钮背后的想法:如果有什么东西按1,如果有什么东西按2,。。。问题是,即使使用plt.ioff(),程序des在显示绘图后也不会停止。在上一个版本中,我使用了您建议的plt.show的顺序,但是如果我丢失了某些必需的命令…我不太确定如何实现这一点。我使用简单的Tkinter库为您创建了一个小GUI。您可以在中看到类PlotClassifier的用法,如果
中的
中的
-part.Wow,令人印象深刻!事实上,我在GUI上遇到了一些问题(代码本身工作得很好!):1)在我的例子中,我需要不同的按钮来实际保存图形并做更多的事情。因此,我想我必须分别构建每个按钮,并且不知道如何在按钮中“排序”它们。2)我在for循环中工作,因此我不能专门为此使用“main”。3)在进入GUI之前已经创建了要绘制的图形。但我想我能自己找到剩下的。谢谢!第三个例子,更像是你需要它。嗯…我对事件的事情仍然有问题。这个想法是对大量的情节进行分析,并根据不同类型的情节进行分类。这就是按钮背后的想法:如果有什么东西按1,如果有什么东西按2,。。。问题是,即使使用plt.ioff(),程序des在显示绘图后也不会停止。在上一个版本中,我使用了您建议的plt.show的顺序,但是如果我丢失了某些必需的命令…我不太确定如何实现这一点。我使用简单的Tkinter库为您创建了一个小GUI。您可以在中看到类PlotClassifier的用法,如果
中的中的-part.Wow,令人印象深刻!事实上,我在GUI上遇到了一些问题(代码本身工作得很好!):1)在我的例子中,我需要不同的按钮来实际保存图形并做更多的事情。因此,我想我必须分别构建每个按钮,并且不知道如何在按钮中“排序”它们。2)我在for循环中工作,因此我不能专门为此使用“main”。3)在进入GUI之前已经创建了要绘制的图形。但我想我能自己找到剩下的。谢谢!第三个例子,更像是你需要它。