簡體   English   中英

在for循環中將事件與matplotlib一起使用

[英]Using events with matplotlib in a for loop

很抱歉,因為我之前已經打開了另一個與相關主題相關的票證。 多虧了我現在得到的答案,我可以更加具體。 我也收到了一些基於Tkinter的解決方案,但是我想用事件和循環解決我的問題。

我正在處理的特殊情況如下:我有一個數組數組。 我希望matplotlib繪制它的第一個元素,讓我按一個鍵(帶有關聯的事件),然后程序繪制第二個數組,相同的行為,依此類推。

作為一個簡單的例子:

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。但是,我得到的是一個繪制有十個向量的圖形,而當我按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:

我認為我沒有正確地解釋自己,數據的種類可能被誤解了。 就我而言,我正在讀取海量數據表,每一行都是不同的來源。 我正在嘗試繪制的Whay是列的信息。 我是物理學家,所以我對時尚編程或其他方面不了解很多。 問題是...如果無法通過for循環執行此操作,有人可以向我解釋一下如果沒有它怎么做這種工作?

您不需要循環。 使用命令fig.canvas.draw()在事件函數ontype新圖。

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()

下一個塊是您要使用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 ,要繪制的內容是yield之后的內容。 請參閱“ yield”關鍵字在Python中做什么? 簡而言之, yield將帶有循環的功能轉換為發電機工廠。

fun = ugly_math()

然后是一個發電機。 當你調用fun.next()它將運行功能ugly_math直到它擊中了yield 然后它將返回產生的值(在本示例中為np.random.random )。 下次調用fun.next()時,它將在循環中保留的位置繼續運行,直到再次達到yield為止。 因此,它正是您想要的。

然后從Holger大量借款:

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')

這使我感到很有趣,我將其保存為要點

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM