将matplotlib窗口从子进程中分离

6 投票
3 回答
3317 浏览
提问于 2025-04-16 06:19

我有一个脚本,它可以创建一个图形,但这个脚本在后台一直运行,直到我关闭那个窗口。我希望它在窗口创建后就能自动退出,这样在命令行里按Ctrl-C就不会关闭窗口了,用户也可以继续在命令行里工作,而不需要手动把它放到后台。我看到过一些使用守护进程的解决方案,但我不想把这个分成两个脚本。请问多进程是最简单的解决办法吗,还是有更简单的方法?

相关的show()命令是脚本执行的最后一条指令,所以我不需要以任何方式保留对窗口的引用。

编辑:我不想把图形保存为文件,我想能够使用这个交互式窗口。基本上就像在bash里运行mian ... &一样。

3 个回答

3

我建议使用 os.fork() 作为最简单的解决方案。它确实是守护进程中使用的技巧,但不需要两个脚本,而且非常简单。比如:

import os

proc_num = os.fork()

if proc_num != 0:
    #This is the parent process, that should quit immediately to return to the
    #shell.
    print "You can kill the graph with the command \"kill %d\"." % proc_num
    import sys
    sys.exit()

#If we've made it to here, we're the child process, that doesn't have to quit.
import matplotlib.pyplot as plt
plt.plot([1,2,3],[4,5,6])
plt.show()
6

刚刚发现了plt.show()中的一个参数。把block设置为False的话,会弹出图形窗口,接着继续执行后面的代码,并且在脚本运行结束后还会停留在解释器里(前提是你是在交互模式下运行的 -i)。

plt.show(block=False)
3

这个在Unix系统上可以用:

import pylab
import numpy as np
import multiprocessing as mp
import os

def display():
    os.setsid()
    pylab.show()

mu, sigma = 2, 0.5
v = np.random.normal(mu,sigma,10000)
(n, bins) = np.histogram(v, bins=50, normed=True)
pylab.plot(bins[:-1], n)
p=mp.Process(target=display)
p.start()

当你在终端运行这个脚本时,会显示出pylab的图形。按下Ctrl-C可以结束主脚本,但图形会继续显示。

撰写回答