将matplotlib换行以将回调管道传回主进程

时间:2014-04-02 17:54:39

标签: python matplotlib multiprocessing

动机我有一个现有的代码库,它包含一个函数库,用于读取磁盘,进行一些计算(主要使用numpy和scipy),然后绘制结果。另外,我有一个执行"元绘图"的功能,这意味着它接收一个文件列表,以及一个请求的绘图类型列表,它循环通过以生成pdf中的绘图网格。

鉴于为每个文件完成的计算是完全独立的,我希望使用multiprocessing模块来获得即时加速是相当容易的。然而,(不出所料)生活似乎并不那么简单。

虚拟示例

from multiprocessing import Pool
import matplotlib.pylab as plt
from numpy.random import random
from time import sleep

def computeAndPlot(a):
    sleep(2) # pretend we're working hard
    plt.imshow(random((10,10))) # plot the "result"

if __name__== "__main__":
    Pool().map_async(computeAndPlot,[(ii,) for ii in xrange(40)]).get()

问题如何将matplotlibmultiprocessing一起使用?我正在寻找一个在matplotlib(例如plt.plot()plt.hold())调用时完全透明的解决方案,但它可能很复杂该过程已启动。真的,我希望能够在同一个图中从多个过程绘制到不同的轴。请注意,我并不真正关心绘图本身的并行化,它是我想要并行执行的文件读取和计算。

可能的解决方案A 我使用plt.pause(0.0001)后跟plt.close()取得了一些成功,这是毫无意义的,但确实证明您确实可以同时从多个流程生成数据,并且可能分别保存每一个。也许这是最合情合理的解决方案,但令人烦恼的是我不知道如何使用它来生成pdf中的图形网格。除非你最后做了一些花哨的pdf合并。

可能的解决方案B 我想知道是否可以包装matplotlib以便将所有函数调用传递回主进程。我想这可以通过使用pipedMPL函数包装器来实现,该包装器将应用于map_async的第一个参数。主过程将接收绘图命令并将其发布到相关轴(它应该知道源过程,以便它可以选择正确的轴)。我觉得这可能是一个很好的解决方案,但我希望编写所需的包装器以正确处理实例方法和所有内容(?)会相当复杂。 问题:这对于其他人可能遇到的困难和有用性是值得追求的还是已经有了更好的解决方案,也有类似模块包装的例子(请注意,这不是基本的猴子修补一两种方法,我想为所有东西编写一个通用的包装器。

可能的解决方案C 我简要地看了一下在子流程中生成轴并将其发送回主流程以在主图中使用的可能性。也许这是可能的,但我无法使它工作......我只是遇到了酸洗错误。

还有其他想法吗?


更新

经过几个小时的工作,我得到了解决方案B的基本版本:monobrow.py (gist)

在轻松包装模块方面,它实际上非常简单(作为状态here):

import sys
sys.module['matplotlib'] = MyFakeMatplotlib()

0 个答案:

没有答案