Python Matplotlib:在多个线程中同时绘图
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4659680/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Matplotlib: simultaneous plotting in multiple threads
提问by Boris
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()). Below is some code that shows this behavior.
我曾希望每个线程都能完成它的绘图并关闭自己(据我所知,Python 在线程通过 run() 中的所有语句时关闭它们)。下面是一些显示此行为的代码。
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.
任何帮助都受到应有的赞赏。
回答by jfs
For pylabinterface there is a solution Asynchronous plotting with threads.
对于pylab接口,有一个解决方案Asynchronous plotting with threads。
Without pylabthere could be different solutions for each matplotlib's backends (Qt, GTK, WX, Tk). The problem is that each GUI toolkit has each own GUI mainloop. You could see how ipythondeals with it.
如果没有pylab,每个 matplotlib 的后端(Qt、GTK、WX、Tk)可能会有不同的解决方案。问题是每个 GUI 工具包都有自己的 GUI 主循环。你可以看到ipython它是如何处理的。
回答by Joe Kington
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. If you want to speed up batch processing on a multicore machine, you're going to need multiprocessing regardless.
Matplotlib 已经线程化,因此您可以一次显示多个图形并与之交互。如果你想在多核机器上加速批处理,无论如何你都需要多处理。
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()

