简体   繁体   English

Matplotlib:在多个线程中同时绘图

[英]Matplotlib: simultaneous plotting in multiple threads

I am trying to do some plotting in parallel to finish large batch jobs quicker. 我正在尝试并行绘图以更快地完成大批量作业。 To this end, I start a thread for each plot I plan on making. 为此,我为我计划制作的每个剧情开始一个主题。

I had hoped that each thread would finish its plotting and close itself (as I understand it, Python closes threads when they get through all the statements in run()). 我曾希望每个线程都能完成它的绘图并自行关闭(据我所知,当Python通过run()中的所有语句时,它会关闭线程)。 Below is some code that shows this behavior. 下面是一些显示此行为的代码。

If the line that creates a figure is commented out, it runs as expected. 如果创建图形的行已注释掉,则按预期运行。 Another plausibly helpful tidbit is that it also runs as expected when you only spawn one thread. 另一个看似合情合理的消息是,当你只生成一个线程时,它也会按预期运行。

import matplotlib.pyplot as plt
import time
import Queue
import threading

def TapHistplots():
    ##  for item in ['str1']:
# # it behaves as expected if the line above is used instead of the one below
    for item in ['str1','str2']:
        otheritem = 1
        TapHistQueue.put((item, otheritem))
        makeTapHist().start()

class makeTapHist(threading.Thread):
    def run(self):
        item, otheritem = TapHistQueue.get()
        fig = FigureQueue.get()
        FigureQueue.put(fig+1)
        print item+':'+str(fig)+'\n',
        time.sleep(1.3)
        plt.figure(fig) # comment out this line and it behaves as expected
        plt.close(fig)

TapHistQueue = Queue.Queue(0)
FigureQueue = Queue.Queue(0)
def main():
    start = time.time()
    """Code in here runs only when this module is run directly"""
    FigureQueue.put(1)
    TapHistplots()
    while threading.activeCount()>1:
        time.sleep(1)
        print 'waiting on %d threads\n' % (threading.activeCount()-1),
    print '%ds elapsed' % (time.time()-start)

if __name__ == '__main__':
    main()

Any help is duly appreciated. 任何帮助都得到了适当的赞赏。

Why not just use multiprocessing? 为什么不使用多处理? As far as I can tell from your description, threading won't help you much, anyway... 至于我从你的描述中可以看出,无论如何,线程对你都没有多大帮助......

Matplotlib already threads so that you can display and interact with multiple figures at once. Matplotlib已经过线程,因此您可以一次显示多个数字并与之交互。 If you want to speed up batch processing on a multicore machine, you're going to need multiprocessing regardless. 如果您想加快多核机器上的批处理速度,您无论如何都需要多处理。

As a basic example ( Warning: This will create 20 small .png files in whatever directory you run it in! ) 作为一个基本示例( 警告:这将在您运行它的任何目录中创建20个小的.png文件!

import multiprocessing
import matplotlib.pyplot as plt
import numpy as np

def main():
    pool = multiprocessing.Pool()
    num_figs = 20
    input = zip(np.random.randint(10,1000,num_figs), 
                range(num_figs))
    pool.map(plot, input)

def plot(args):
    num, i = args
    fig = plt.figure()
    data = np.random.randn(num).cumsum()
    plt.plot(data)
    plt.title('Plot of a %i-element brownian noise sequence' % num)
    fig.savefig('temp_fig_%02i.png' % i)

main()

For pylab interface there is a solution Asynchronous plotting with threads . 对于pylab接口,有一个解决方案是使用线程进行异步绘图

Without pylab there could be different solutions for each matplotlib's backends (Qt, GTK, WX, Tk). 如果没有pylab ,每个matplotlib的后端可能会有不同的解决方案(Qt,GTK,WX,Tk)。 The problem is that each GUI toolkit has each own GUI mainloop. 问题是每个GUI工具包都有自己的GUI主循环。 You could see how ipython deals with it. 您可以看到ipython如何处理它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM