0

以前に関連トピックについて別のチケットを開いたことがあるので、お詫び申し上げます。私が今得た答えのおかげで、私はより具体的にすることができます。Tkinterをベースにした解決策もいくつか受け取りましたが、イベントとループの問題を解決したいと思います。

私が扱っている特定のケースは次のとおりです。配列の配列があります。matplotlibにその最初の要素をプロットさせ、1つのキー(関連するイベントを含む)を押して、プログラムが2番目の配列、同じ動作などをプロットできるようにします。

簡単な例として:

import matplotlib.pyplot as plt
import numpy as np

# Define the event
def ontype(event):
    if event.key == '1':
        print 'It is working'
        plt.clf()

# Create figure an connect the event to it
fig=plt.figure(figsize=(16,8))
plt.gcf().canvas.mpl_connect('key_press_event',ontype)

# Loop
for element in xrange(10):
    #This mimicks the "array of arrays" generating a random array in each loop
    vector = np.random.random(10)  
    plt.plot(vector)
    plt.show()

最初のプロット(ループが最初に実行されるとき)が得られ、1を押すまで開いたままになると予想されます。ただし、得られるのは10個のベクトルがプロットされた図であり、1を押すと図は次のようになります。クリアされ、端末から「動作中」と表示されます。最初の要素をプロットし、キーが押されたら次の要素に移動するプログラムが必要です。これに関するヒントはありますか?私は何が間違っているのですか?

君たちありがとう!

編集:

原則として、プログラムの構造を変更することはできず、何かをプロットする前にさまざまなものを計算するためにforループが必要であることに注意してください。したがって、プログラムは行く必要があります

def ontype(event):
     define event

Some stuff
elements = array of arrays
for element in elements:
    do more stuff
    plot element and "stay" in this plot untill any event key is pressed. And then, go to the next element in elements and do the same

編集2:

自分のことをきちんと説明しておらず、データの種類が誤解されていたのではないかと思います。私の場合、私は膨大なデータの表を読んでおり、各行は異なるソースです。私がプロットしようとしているのは、列の情報です。私は物理学者なので、スタイリッシュなプログラミングなどについてはあまり知識がありません。問題は...forループでこれを行う方法がない場合、誰かがそれなしでこの種の作業を行う方法を私に説明できますか?

4

2 に答える 2

2

forこの次のブロックは、ループ で必要なことを実行します。

def ugly_math():
    print 'you will hit this once'
    for j in range(10):
        print 'loop ', j
        # insert math here
        yield  np.random.random(10) * j

あなたのforループは関数に入りますugly_math、そしてあなたがプロットしたいのは後に続くものですyieldPythonで「yield」キーワードは何をするのかを参照してください。。つまり、yieldループのある関数をジェネレーターファクトリーに変えます。

fun = ugly_math()

その後、ジェネレータです。呼び出すと、に当たるまでfun.next()関数が実行されます。次に、生成された値を返します(この例では)。次に電話をかけると、ループの途中で中断したところから再開し、再びヒットするまで実行されます。したがって、それはまさにあなたが望むことをします。ugly_mathyieldnp.random.randomfun.next()yield

次に、ホルガーから多額の借金をします。

fun = ugly_math()
cid_dict = {}
# Define the event
def ontype(event):
    if event.key == '1':
        print 'It is working'
        try:
            vector = fun.next()
            plt.plot(vector)
            fig.canvas.draw()
        except StopIteration:
            plt.gcf().canvas.mpl_disconnect(cid_dict['cid'])
            del cid_dict['cid']

# Create figure an connect the event to it
fig=plt.figure(figsize=(16,8))
cid_dict['cid'] = plt.gcf().canvas.mpl_connect('key_press_event',ontype)

vector = np.random.random(10)  
plt.plot(vector)
plt.show()

ジェネレーターを使い果たしたcid_dict後にコールバックを削除できるようにするためにあります。

これをすべてクラスにまとめることができます

class push_to_advance(object):
    def __init__(self):
        self.fig = plt.figure()
        self.ax = self.fig.gca()
        self.bound_keys = []
        self.bound_cid = {}

    def add_step_through(self, gen, key):
        key = key[0] # make a single char
        if key in self.bound_keys:
            raise RuntimeError("key %s already bound"%key)
        first_data = gen.next()
        self.ax.plot(first_data)
        self.fig.canvas.draw()
        self.bound_keys.append(key)
        def ontype(event):
            if event.key == key:
                try:
                    self.ax.plot(gen.next())
                    self.fig.canvas.draw()
                except StopIteration:
                    self.fig.canvas.mpl_disconnect(self.bound_cid[key])
                    del self.bound_cid[key]
                    self.bound_keys.remove(key)

        self.bound_cid[key] = self.fig.canvas.mpl_connect('key_press_event', ontype)

これはそのように使用されます:

 pta = push_to_advance()
 gen = ugly_math()
 pta.add_step_through(gen,'a')

反復可能なものは、少し精巧に動作します。

 test_array = np.arange(100).reshape(10,10)
 pta.add_step_through(test_array.__iter__(), 'b')

これは私が要点としてそれを保存したのに十分面白かったです。

于 2013-01-16T05:41:27.583 に答える
1

ループは必要ありません。ontypeコマンドを使用して、イベント関数で新しいプロットを再描画しますfig.canvas.draw()

import matplotlib.pyplot as plt
import numpy as np

# Define the event
def ontype(event):
    if event.key == '1':
        print 'It is working'
        vector = np.random.random(10)  
        plt.plot(vector)
        fig.canvas.draw()

# Create figure an connect the event to it
fig=plt.figure(figsize=(16,8))
plt.gcf().canvas.mpl_connect('key_press_event',ontype)

vector = np.random.random(10)  
plt.plot(vector)
plt.show()
于 2013-01-15T22:22:00.983 に答える