(Python)Matplotlib Pyplot Show() .. 阻塞还是非阻塞?

6
我一再遇到使用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()相同的行为),或者这种代码需要完全重新考虑/重写?

3个回答

2

一些不同质量的想法:

如果您不喜欢全局变量 s,您可以将 onclick() 作为可调用对象并将其附加到该对象。

您的回调功能可以获取/释放锁以控制程序流程(有点脏)。

您可以主动轮询 s 以控制程序流程(非常肮脏)。

您可以通过 fig.canvas.draw() 手动控制图形的绘制。


感谢您的想法。我能够通过从源代码构建mpl来更改show()的阻塞行为。 - wim

1

今天我成功解决了我的问题。如果其他人也想改变show()的行为,可以继续阅读以下内容:

我在matplotlib网页的最新消息部分注意到了这个标题为支持多次调用show的段落:

长期以来的一个请求是支持多次调用show()。这很困难,因为很难在操作系统、用户界面工具包和版本之间获得一致的行为。Eric Firing在统一后端上做了很多工作,期望的行为是使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' 

0

我注意到在运行代码时有以下两种方式:

  1. 直接在Python解释器(命令行)中运行

  2. 将其放入Python脚本中,并从命令行运行(“python script.py”)

两种方式都会产生阻塞行为,这是可以接受的。

从解释器中,两个图像都会出现;而从命令行中,只有第一个图像出现。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接