2

プロットを作成し、プロットが示す内容に応じていずれかのボタンを押してから、次のオブジェクトをプロットできるようにしたいと考えています。ただし、ボタンが押されるまで「待機」できないようです。また、何かを保存するためのパスなど、いくつかのパラメーターを press_event に渡すことができるかどうか疑問に思っています。

これが役立つ場合のプログラムのスキームです。よろしくお願いします!

# 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)
4

1 に答える 1

4

plt.gcf().canvas.mpl_connect('key_press_event',ontype)の前に電話する必要がありますplt.show()。非対話モードでは、実行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 が作成された後にプロットを行う関数を提供する必要があります。

于 2013-01-15T12:35:43.583 に答える