我一遍又一遍地遇到show()
这个问题,我确信我做错了但不确定做出我想要的'正确'方法。
并且[我认为]我想要的是在主线程中阻塞直到GUI线程中发生事件的某种方式,这样的东西第一次起作用:
from matplotlib import pyplot as p
from scipy import rand
im = (255*rand(480,640)).astype('uint8')
fig = p.figure()
ax = fig.add_subplot(111)
ax.imshow(im)
# just any mutable container for storing a click
s = [-1, -1]
def onclick(event):
if event.xdata is not None and event.ydata is not None:
s[0] = event.xdata
s[1] = event.ydata
p.close()
cid = fig.canvas.mpl_connect('button_press_event', onclick)
p.show()
print s
p.show()
阻塞,直到在事件处理程序中调用p.close()
。但是当第二次运行相同的代码时,它会超过p.show()
并打印原始s, [-1, -1]
。
我已阅读有关p.show()
是否可以或应该在同一程序中多次调用的相互矛盾的信息。它似乎被设计为使用一次,并且只在脚本结束时使用一次。其他用例似乎以某种方式中断pyplot
(状态机?)。
我尝试使用p.draw()
和p.ion()
以及p.ioff()
的组合,但无法获得我想要的行为(要么事情没有正确阻止,要么情节不是'出现在正确的时间)。
我也很困惑事件处理程序如何能够在这里看到s
,以及这是否是一种传递/传出信息的糟糕方式。如果我不使用像数组或列表这样的可变容器,那么我想要的事件处理程序设置的信息就会作为局部变量丢失。是否有一些我错过的其他方法,GUI线程可以将信号传递回主线程?有没有办法在继续之前阻止来自事件处理程序的信号,而不是定期轮询或忙等待?
所以我猜最终我的主要问题是:
p.show()
是否有一个简洁的替代品,它可以满足我的需求(第一次与p.show()
相同的行为),或者这种代码是否需要完全重新思考/重写?
答案 0 :(得分:2)
结合不同质量的想法:
如果你不喜欢s是一个全局变量,你可以让onclick()一个可调用的对象将它附加到它。
你的回调可以获取/释放一个锁来控制程序流(很脏)。
你可以主动轮询s来控制程序流程(非常脏)。
您可以通过fig.canvas.draw()
手动控制图形的绘制答案 1 :(得分:1)
我今天能够解决我的问题。如果其他人有兴趣改变show()
的行为,请继续阅读,了解如何做到这一点:
我注意到在matplotlib网页的what's new部分标题为多次调用以显示支持的的段落:
长期存在的要求是支持多次调用show()。这很困难,因为很难在操作系统,用户界面工具包和版本之间获得一致的行为。 Eric Firing在后端合理化show方面做了大量工作,所需的行为使show显示所有新创建的数据并阻止执行直到它们关闭。重复调用show应该会提升自上次调用以来新创建的数字。 Eric已经对用户界面工具包以及他可以访问的版本和平台进行了大量测试,但是无法对它们进行全部测试,因此请将问题报告给邮件列表和错误跟踪器。
这是版本1.0.1
的'新内容',在撰写时,synaptic中的版本仍然在0.99.3
上。我能够从源v1.0.1
下载和构建。我还需要满足依赖性的其他包libfreetype6-dev tk-dev tk8.5-dev tcl8.5-dev python-gtk2-dev
。
现在使用matplotlib.__version__ == 1.0.1
,以下代码会阻止我的期望:
import matplotlib.pyplot as p
from scipy import eye
p.imshow(eye(3))
p.show()
print 'a'
p.imshow(eye(6))
p.show()
print 'b'
p.imshow(eye(9))
p.show()
print 'c'
答案 2 :(得分:0)
我发现运行代码
之间存在差异直接在Python解释器(命令行)
将其放入Python脚本并从命令行运行(“python script.py”)
两者都给出阻止行为,这没关系。
从解释器出现两个图像,从命令行只出现第一个图像。