Matplotlib的ion()和子进程

7

我正在尝试让一个图表弹出来,以便用户可以确认拟合是否成功,但不会因此挂起整个流程。然而,虽然窗口出现了,但里面从来没有任何东西,而且它是“未响应”的。我怀疑这与子进程功能有不良互动有关,因为这段代码是用于前端和数据处理的模拟运行在 C++ 中。

import subprocess
import numpy as np
from matplotlib import pyplot as mpl
...
mpl.ion()
fig = mpl.figure()
ax = fig.add_subplot(1,1,1)
ax.grid(True)
ax.plot(x, y, 'g')
ax.scatter(X, Y, c='b')
ax.scatter(min_tilt, min_energy, c='r')
mpl.draw()
...
subprocess.call(prog)

以下子进程确实打开。如果我删除ion()的调用并使用mpl.show(),那么绘图可以正常工作,但整个过程会一直等待窗口关闭。我需要在用户查看图形时继续进行该过程。有没有方法可以做到这一点?
2个回答

8

请尝试使用mpl.draw()之外的方法:

mpl.pause(0.001)

当使用 matplotlib 的交互模式ion()时,请注意这仅适用于matplotlib 1.1.1 RC或更高版本。


1
这会绘制窗口并继续处理,但窗口立即变为“未响应”,关闭它将停止整个过程。 - Elliot
@Elliot:当您关闭交互模式时,使用plt.show(block=False)是否会产生相同的效果? - pelson
1
在添加mpl.pause(0.0001)而非mpl.draw()的同时,成功显示了图表,但每当我尝试单击它时,窗口就会进入“未响应”状态。有人知道原因吗? - blue_chip

1

这可能有些过度,但由于没有更好的解决方案,我使用了线程模块并且它起作用了。如果有人有更简单的方法,请告诉我。

import subprocess
import threading
from matplotlib import pyplot as mpl
...
class Graph(threading.Thread):
   def __init__(self,X,Y,min_tilt, min_energy):
       self.X = X
       self.Y = Y
       self.min_tilt = min_tilt
       self.min_energy = min_energy
       threading.Thread.__init__(self)

   def run(self):
       X = self.X
       Y = self.Y
       dx = (X.max()-X.min())/30.0
       x = np.arange(X.min(),X.max()+dx,dx)
       y = quad(x,fit)
       fig = mpl.figure()
       ax = fig.add_subplot(1,1,1)
       ax.grid(True)
       ax.plot(x, y, 'g')
       ax.scatter(X, Y, c='b')
       ax.scatter(self.min_tilt, self.min_energy, c='r')
       mpl.show()
thread = Graph(X,Y,min_tilt,min_energy)
thread.start()

嗯,看起来如果前一个窗口在下一个窗口打开之前没有关闭,会出现问题。有人知道如何修复这个问题,使其可以打开任意数量的窗口吗? - Elliot

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