Matplotlib和: RuntimeError:主线程不在主循环中:

18

我想在Python下同时运行多个重复任务。虽然我对多进程编程还不是很熟悉,但由于所有的任务都是独立的,所以我使用了以下简单的代码:

    import numpy as np
    import sys
    import os
    import glob
    import matplotlib.pyplot as plt
    import concurrent.futures as Cfut
    
    def analize(simul, N_thread):
        path = os.getcwd()

        print('Analizing topo ...')
        Data = output of some calculations
    
        print('Writing Data ...')
        np.save('Data', Data)
    
        print('Data saved')
        print('Printing figures')

        plt.figure()
        plt.plot(Data[0])
        plt.savefig('figure1.pdf')

        plt.clf()
        plt.plot(Data[0])
        plt.savefig('figure1.pdf')

        plt.close('all')
        print('figures saved')
        os.chdir(path

if __name__ == '__main__':
    list_simul = sorted(glob.glob('Layer*'))
    executor = Cfut.ProcessPoolExecutor(5)
   #executor = Cfut.ThreadPoolExecutor(N_jobs)
    futures = [executor.submit(analize, item, 10) for item in list_simul]
    Cfut.wait(futures)

它在3个月里运行得非常好,但自从今天早上开始,有时会出现以下错误:

Exception ignored in: <bound method Image.__del__ of <tkinter.PhotoImage object at 0x7fac6c187f98>>
    Traceback (most recent call last):
      File "/usr/lib/python3.5/tkinter/__init__.py", line 3359, in __del__
        self.tk.call('image', 'delete', self.name)
    RuntimeError: main thread is not in main loop

奇怪的是,有些工作可以顺利完成,而且不是每次都会出现问题。经过一番研究,我找到了许多与此问题有关的帖子,它们都与图形用户界面有关。我理解了这个问题,但我想我应该能够找到一个解决方法,因为我没有显示任何图像,只是创建并保存对象,并且所有任务都是独立的。

有什么提示吗?

2个回答

23

此处所示,您尝试过将以下代码添加到导入的顶部吗?

import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt

17

matplotlib默认使用TkAgg。像TkAgg, FltkAgg, GTK, GTKAgg, GTKCairo, WxWxAgg等后端都是基于GUI的。大多数GUI后端需要在主线程中运行。因此,如果您在没有GUI的环境下运行,它将会抛出RuntimeError: main thread is not in main loop错误。

因此,只需切换到不使用GUI的后端:AggCairoPSPDFSVG

例如:

import matplotlib.pyplot as plt
plt.switch_backend('agg')

参考资料: https://matplotlib.org/stable/faq/howto_faq.html#work-with-threads


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