10

我想使用matplotlib生成一些 PDF 文件。我的主要问题是 matplotlib 很慢,每个文件需要 0.5 秒。

我试图弄清楚为什么需要这么长时间,我编写了以下测试程序,它只是将一条非常简单的曲线绘制为 PDF 文件:

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

X = range(10)
Y = [ x**2 for x in X ]

for n in range(100):
    fig = plt.figure(figsize=(6,6))
    ax = fig.add_subplot(111)
    ax.plot(X, Y)
    fig.savefig("test.pdf")

但即使是这么简单的事情也需要很多时间:100 个 PDF 文件总共需要 15-20 秒(现代英特尔平台,我尝试了 Mac OS X 和 Linux 系统)。

有什么技巧和技术可以用来加速 matplotlib 中的 PDF 生成吗?显然我可以在多核平台上使用多个并行线程,但我还能做些什么吗?

4

4 回答 4

4

如果可行,您可以使用多进程来执行此操作(假设您的机器上有多个内核):

注意:以下代码将在您机器上的当前目录中生成 40 个 pdf

import matplotlib.pyplot as plt

import multiprocessing


def do_plot(y_pos):
    fig = plt.figure()
    ax = plt.axes()
    ax.axhline(y_pos)
    fig.savefig('%s.pdf' % y_pos)

pool = multiprocessing.Pool()

for i in xrange(40):
    pool.apply_async(do_plot, [i])

pool.close()
pool.join()

它不能完美地扩展,但通过在我的 4 个内核(具有超标题的双核)上执行此操作,我得到了显着提升:

$> time python multi_pool_1.py 
done

real    0m5.218s
user    0m4.901s
sys 0m0.205s

$> time python multi_pool_n.py 
done

real    0m2.935s
user    0m9.022s
sys 0m0.420s

我确信 mpl 的 pdf 后端有很大的性能改进空间,但这不在您所追求的时间范围内。

高温下,

于 2012-08-19T14:45:15.433 回答
3

Matplotlib has a lot of overhead for creation of the figure, etc. even before saving it to pdf. So if your plots are similar you can safe a lot of "setting up" by reusing elements, just like you will find in animation examples for matplotlib.

You can reuse the figure and axes in this example:

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

X = range(10)
Y = [ x**2 for x in X ]
fig = plt.figure(figsize=(6,6))
ax = fig.add_subplot(111)


for n in range(100):
    ax.clear() # or even better just line.remove()
               # but should interfere with autoscaling see also below about that
    line = ax.plot(X, Y)[0]
    fig.savefig("test.pdf")

Note that this does not help that much. You can save quite a bit more, by reusing the lines:

line = ax.plot(X, Y)[0]
for n in range(100):
    # Now instead of plotting, we update the current line:
    line.set_xdata(X)
    line.set_ydata(Y)
    # If autoscaling is necessary:
    ax.relim()
    ax.autoscale()

    fig.savefig("test.pdf")

This is close to twice as fast as the initial example for me. This is only an option if you do similar plots, but if they are very similar, it can speed up things a lot. The matplotlib animation examples may have inspiration for this kind of optimization.

于 2012-08-26T14:15:56.213 回答
0

您可以使用报告实验室。开源版本应该足以做你想做的事情。它应该比使用 matplotlib 生成 pdf 快得多。

于 2012-08-19T13:18:03.247 回答
0

我认为更改库(matplotlib)不是您的选择,因为您实际上喜欢 matplotlib 产生的内容:-)。我还假设——这里的一些人已经对此发表了评论——matplotlib 的其他后端并没有明显更快。我认为在每台机器和具有良好任务调度程序的操作系统的这些日子里,并行运行像您这样的作业以优化吞吐量(即 PDF 文件创建速率)是很好的。我认为您将设法以合理的计算能力每秒生成大量文件。这要走的路,所以我真的相信你的问题很有趣,但在实践中并不真正相关。

于 2012-08-30T14:35:14.687 回答