pyplot在第一次显示/关闭图之后缺少第一个事件

时间:2016-03-11 21:12:09

标签: python matplotlib event-handling imshow

我试图在matplotlib图中迭代一系列图像,并为每张图像记录一系列事件(鼠标点击和按键)。然而,在第一个数字之后,第一个事件被错过了。

例如,在以下MLE中,如果用户按下' q'在显示第一图像之后,然后显示第二图像。但是,如果用户然后按下“q”。这个事件再次被错过了,他们必须按下' q'在第二张图片关闭之前第三次。

from numpy import *
from matplotlib import pyplot as plt
from matplotlib.pyplot import figure, show, draw

class guiBackend:
  def __init__(self, srcImage):

    self.srcImage = srcImage
    self.fig = figure(figsize=(16,16), frameon=False)
    self.axSrc = self.fig.add_subplot(111, autoscale_on=True)
    self.showObj = self.axSrc.imshow(self.srcImage)

    self.cidKey = self.fig.canvas.mpl_connect('key_press_event', self.pressButton)

  def pressButton(self, event):
    if event.key == 'q':
      self.fig.canvas.mpl_disconnect(self.cidKey)
      plt.close(self.fig)
      return
    else:
      self.srcImage = random.randint(0, 256, size=(128,128,3))
      self.showObj.set_data(self.srcImage)
      self.fig.canvas.draw()


def main():

  for k in xrange(2):
    img = random.randint(0, 256, size=(128,128,3))
    imgObj = guiBackend(img)
    plt.show()

  return 1

根据我收集的信息,这是由于多次调用show()close(),但我无法找到在循环的每次迭代期间阻止程序的另一种方法为了收集一系列用户输入,直到用户按下“q”。

1 个答案:

答案 0 :(得分:0)

我无法重现这个问题(缺少事件)运行(排序)1.5.x分支。至于你的第二个问题,我建议通过生成器将循环注入到gui处理代码中:

import numpy as np
from matplotlib import pyplot as plt

class guiBackend:
    def __init__(self, img_gen):

        self.img_gen = iter(img_gen)
        self.cur_image = next(self.img_gen)

        self.fig = plt.figure(figsize=(16, 16), frameon=False)
        self.axSrc = self.fig.add_subplot(111, autoscale_on=True)
        self.im = self.axSrc.imshow(self.cur_image)

        self.cidKey = self.fig.canvas.mpl_connect('key_press_event',
                                                  self.button_press)

    def button_press(self, event):
        print("in handler")
        print('got key {}'.format(event.key))
        if event.key == 'q':
            try:
                self.cur_image = next(self.img_gen)
            except StopIteration:
                plt.close(self.fig)
                return
            self.im.set_data(self.cur_image)
            self.fig.canvas.draw_idle()


def image_gen(n):
    for k in range(n):
        yield np.random.randint(0, 256, size=(128, 128, 3))
# need to hold on to this or callback gets gc'd
gui_backend = guiBackend(image_gen(5))
plt.show()