从iPython shell运行时,matplotlib mpl_connect中的事件滞后 [英] Event lag in matplotlib mpl_connect when run from iPython shell

查看:933
本文介绍了从iPython shell运行时,matplotlib mpl_connect中的事件滞后的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图写一个非常简单的小'gui',它允许用户点击图像并将位置和值打印到屏幕上。我的工作原理,但我发现从iPython shell运行时,打印输出有1个事件延迟。



当我运行时例行程序,第一次点击不做任何事情。第二次单击允许第一次单击的打印输出显示。当我右键单击(这是我想要的)时,例程退出正常,但奇怪的是必须有一个缓冲区仍然存在,因为如果我再次运行例程,那么在我甚至做任何事之前都会打印最后一次点击的值。 / p>

以下是代码:

 将matplotlib.pyplot导入为plt 
import numpy as np

def pickPoint(data):
在屏幕上显示2D数组,并根据用户点击打印数据信息。

def pickPointSelectVal(事件):
if event.button == 3:
fig.canvas.mpl_disconnect(cid)
plt.close(fig)
else :
print'get click:',event.x,',',event.y,'value:',data [event.x,event.y]

dims = data .shape
dpi = 96.0
fdims =(x / dpi代表dims)

fig = plt.figure(figsize = fdims,dpi = dpi)
plt.figimage(data.transpose(),origin ='lower',cmap ='gray')
cid = fig。 canvas.mpl_connect('button_press_event',pickPointSelectVal)

如果__name__ ==__ main__:
a = np.arange(500)
b = np.reshape(np.repeat( a,100),(500,100))
c = b * np.reshape(np.repeat(np.arange(100),500),(100,500))。transpose()
pickPoint(c)

只需点击几下运行两次只有第一次产生以下输出:

 在[1]中:pickPoint(c)
得到点击:60,80.0值:4800
得到点击:45,25.0价值:1125
得到点击:
在[2]:pickPoint(c)
267,76.0价值:20292

c是虚拟数组。请注意,当我从普通的Python shell运行相同的例程时,不会发生这种延迟,但在这种情况下它似乎也没有正确退出。我很想知道区别是什么,以及我写的东西是否有些怪异。



我在Spyder 2.2.5里面运行这个在Windows 7 64位上安装Anaconda 1.8。



ADD:
我在iPython qtconsole和普通iPython中试过这个,都使用Qt4Agg后端。使用qtconsole时会出现问题,但使用普通iPython时则不会出现此问题。有人知道两者之间的事件处理方式有何不同吗?

解决方案

好吧,我设法跟踪了这一点 - 事实证明这是QtConsole的一个已知问题,其根本原因与这个问题(Canopy和Spyder在他们的GUI中使用ipython qtconsole)。问题是第一次打印不会触发stdout的冲洗(可以找到几年前更好的解释这里),所以你必须a)手动完成,如下所示,或b)使用ipython -u作为无缓冲输出,我还没有尝试过。手动刷新对我来说会很好,所以我现在就用它。



如果我将以下内容添加到我的代码中,它会按预期工作:

  import sys 

#(把这个放在print语句之后)
sys.stdout.flush()


I am attempting to write a very simple little 'gui' which will allow the user to click on an image and have the position and the value printed to the screen. What I have works, but I've discovered that when running it from an iPython shell, there is a 1-event delay in the printed output.

When I run the routine, the first click doesn't do anything. The second click allows the printed output from the first click to show up. The routine exits okay when I right-click (which is what I want), but oddly enough there must be a buffer still around because if I run the routine again, the values from that last click get printed before I even do anything.

Here is the code:

import matplotlib.pyplot as plt
import numpy as np

def pickPoint(data):
    """Displays a 2D array on the screen and prints data info based upon user clicks."""

    def pickPointSelectVal(event):
        if event.button == 3:
            fig.canvas.mpl_disconnect(cid)
            plt.close(fig)
        else:
            print 'got click: ', event.x, ',', event.y, ' value: ', data[event.x,event.y]

    dims = data.shape
    dpi = 96.0
    fdims = (x/dpi for x in dims)

    fig = plt.figure(figsize=fdims, dpi=dpi)
    plt.figimage(data.transpose(),origin='lower',cmap='gray')
    cid = fig.canvas.mpl_connect('button_press_event', pickPointSelectVal)

if __name__ == "__main__":
    a = np.arange(500)
    b = np.reshape(np.repeat(a,100),(500,100))
    c = b * np.reshape(np.repeat(np.arange(100),500),(100,500)).transpose()
    pickPoint(c)

running it twice with a few clicks only on the first time yields the following output:

In [1]: pickPoint(c)
got click:  60 , 80.0  value:  4800
got click:  45 , 25.0  value:  1125
got click:
In [2]: pickPoint(c)
 267 , 76.0  value:  20292

"c" is dummy array. Note that this delay doesn't happen when I run the same routine from a normal Python shell, but it also doesn't appear to exit correctly in that case. I'd love to know what the difference is, and if there is something kooky with what I've written.

I'm running this inside Spyder 2.2.5 from an install of Anaconda 1.8 on Windows 7 64-bit.

ADD: I have tried this in iPython qtconsole and plain iPython, both using the Qt4Agg backend. The problem occurs when using qtconsole, but not when using plain iPython. Does someone know how events may be handled differently between the two?

解决方案

Well, I managed to track this down - it turns out that this is an known issue with QtConsole, and the underlying cause is the same as this question (both Canopy and Spyder use ipython qtconsole in their GUIs). The issue is that the first print doesn't trigger a flush of stdout (a much better explanation from a couple years ago can be found here), so you have to a) do it manually, as below, or b) use ipython -u for unbuffered output, which I haven't tried. Flushing manually will work fine for me, so I'll go with that for now.

If I add the following to my code it works as expected:

import sys

# (put this after the print statement)
sys.stdout.flush()

这篇关于从iPython shell运行时,matplotlib mpl_connect中的事件滞后的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆