【问题标题】:matplotlib: faster PDF generation?matplotlib:更快的 PDF 生成?
【发布时间】:2012-08-15 03:17:14
【问题描述】:

我想使用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 秒(现代 Intel 平台,我尝试过 Mac OS X 和 Linux 系统)。

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

【问题讨论】:

  • 如您所见,我没有答案,但我有适当的参考资料。这里有一张开发票:github.com/matplotlib/matplotlib/issues/992,这里有一个邮件列表问题存档:sourceforge.net/mailarchive/…
  • 我试图用一个简单的绘图创建一个 pdf 文件(使用数组进行绘图),我花了 72ns 来创建一个文件。你依赖你在这里创建的列表吗?如果没有,我可以发布我的解决方案。
  • @PateToni:这里输入格式无关紧要,数据转换比绘图快很多。 :)
  • @JukkaSuomela:对不起,但我发现,我在 Windows 机器上的 python 版本有点坏了。它没有告诉我正确的时机。 72ns 不是真的。我的笔记本上没有任何加速。根据分析,瓶颈位于 matplotlib 内部。只需尝试一些替代方案(PyCha,...)或搜索更快的机器来工作 =)
  • stackoverflow.com/questions/4690585/… 是您正在寻找的答案吗?

标签: python matplotlib pdf-generation


【解决方案1】:

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

注意:以下代码将在您机器上的当前目录中生成 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 后端有很大的性能改进空间,但这不在您所追求的时间范围内。

HTH,

【讨论】:

  • 不幸的是,这并没有真正回答我的问题。我写道:“显然我可以在多核平台上使用多个并行线程,但我还能做些什么吗?”
  • 有时你必须务实。使用 reportlab 并不能回答您的问题“我可以使用任何技巧和技术来加快 matplotlib 中的 PDF 生成速度吗?”两者都可以,但在某些情况下这是一个很好的建议。
  • 请不要误会我的意思;使用多核计算机(更一般地说,集群环境)是加速计算的一种非常好的方法,特别是如果计算很容易并行化,就像这里的情况一样。但是,这是我已经知道并且已经在做的事情;我的问题是关于加速 matplotlib 的其他可能方法。毕竟,并行内核的数量仍然有些有限,并且集群环境有它们的开销。运行在 > 2GHz 的单核应该每秒能够生成超过 5 个简单的 PDF 图形。 :)
  • 最后,滥用原始计算机能力和并行线程是实现显着加速的唯一方法。在我的实际应用程序中,使用一个特定的测试数据集,我自己的计算机的原始运行时间为 63 秒。高端服务器使用单个 CPU 将其提高到 29 秒,而使用多处理则只需 6 秒(8 核 + 超线程)。并行使用多个服务器将其压缩到 4 秒,现在瓶颈已经在应用程序的其他部分,与 matplotlib 完全无关。一个可怕的矫枉过正,但我​​现在很高兴。 :)
【解决方案2】:

Matplotlib 在创建图形等方面有很多开销,甚至在将其保存为 pdf 之前也是如此。因此,如果您的情节相似,您可以通过重用元素来保护很多“设置”,就像您在 matplotlib 的动画示例中找到的那样。

您可以在此示例中重复使用图形和轴:

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")

请注意,这并没有太大帮助。通过重复使用这些行,您可以节省更多:

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")

对我来说,这几乎是最初示例的两倍。如果你做相似的情节,这只是一个选择,但如果它们非常相似,它可以加快速度。 matplotlib animation examples 可能对这种优化有启发。

【讨论】:

  • 谢谢,这些都是好主意。不幸的是,在我的实际应用程序中,实际的 savefig 调用似乎占用了总运行时间的 50% 以上。
  • @JukkaSuomela,没错,这对 savefig 本身应该没有太大的影响。我唯一的想法是尝试另一个后端,但我怀疑它会产生很大的不同......
  • “pdf”后端似乎和“Agg”一样慢。使用“ps”后端生成 PostScript 文件会更快一些(但我需要将 PS 转换为 PDF)。
  • @JukkaSuomela 试试 cairo.pdf 吧?虽然我猜结果可能看起来有点不同。
  • cairo.pdf 似乎稍快但不多。
【解决方案3】:

您可以使用Report Lab。开源版本应该足以做你想做的事情。它应该比使用 matplotlib 生成 pdf 快很多。

【讨论】:

  • 我可以轻松地将使用 matplotlib 的现有代码转换为使用 Report Lab 吗?输出的质量是否与 matplotlib 相提并论?
  • 编码会稍微复杂一些。您可以创建一个 jpg,然后将其嵌入到 pdf 中。 2.1.3 Can I use any images?。或者,您也可以重写它以使用 Reportlab Platypus。两者都应该更快,因为 matplotlib 图像生成比 pdf 生成更快。或者,我工作的一位研究人员使用pdfrw,并对此发誓。我相信 matplotlib 生成 pdf 的速度如此之慢的原因是因为它将它们转换为乳胶,然后使用 sphinx 转换为 pdf。
【解决方案4】:

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

【讨论】:

    猜你喜欢
    • 2011-05-10
    • 2017-12-14
    • 1970-01-01
    • 2020-07-05
    • 2016-08-24
    • 2015-02-25
    • 2021-03-17
    • 2012-02-21
    • 2011-04-20
    相关资源
    最近更新 更多