You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

深度学习项目:如何用Matplotlib快速生成数百万张PNG图像?

大规模合成绘图提速方案(250万张224×224图像生成)

问题背景

我在深度学习项目中需要为数据集生成250万张224×224像素的合成绘图。目前本机运行100次生成耗时2.7秒,按此速度完成全部任务需约18小时,寻求可行的提速方法。

当前使用的代码:

from matplotlib.backends.backend_agg import FigureCanvasAgg as FigureCanvas
import matplotlib.pyplot as plt

for i in range(100):
    fig = plt.Figure(frameon=False, facecolor="white", figsize=(4, 4))
    ax = fig.add_subplot(111)
    ax.axis('off')
    ax.plot([1, 2, 3, 4, 5, 6, 7, 8], [2, 4, 6, 8, 8, 6, 4, 3])
    canvas = FigureCanvas(fig)
    canvas.print_figure(str(i), dpi=56)

示例生成图像:
示例图像

说明:实际生成会使用200行数据,但该因素对生成速度影响极小。


可行提速方案

1. 复用Matplotlib核心对象,避免重复初始化

每次循环创建fig、ax是主要性能开销点。提前初始化一次画布和轴,循环中仅更新数据:

from matplotlib.backends.backend_agg import FigureCanvasAgg as FigureCanvas
import matplotlib.pyplot as plt

# 提前完成初始化
fig = plt.Figure(frameon=False, facecolor="white", figsize=(4, 4))
ax = fig.add_subplot(111)
ax.axis('off')
canvas = FigureCanvas(fig)
line, = ax.plot([])  # 初始化空折线

for i in range(100):
    # 更新折线数据
    line.set_data([1, 2, 3, 4, 5, 6, 7, 8], [2, 4, 6, 8, 8, 6, 4, 3])
    # 若数据范围固定可省略以下两行
    ax.relim()
    ax.autoscale_view()
    # 保存图像
    canvas.print_figure(str(i), dpi=56)

该方案可减少30%-50%的单循环耗时。

2. 替换为轻量绘图库

Matplotlib偏向交互式绘图,批量生成场景下冗余开销大,可尝试以下替代:

  • Pillow + NumPy:直接操作像素数组绘制折线,完全绕过Matplotlib抽象层,速度提升数倍。核心思路:创建224×224的空白NumPy数组,通过数值计算标记折线像素点,再转成Pillow图像保存。
  • pycairo:底层绘图库,直接生成像素数据,性能远优于Matplotlib,适合高性能需求场景。
  • Plotly Orca:无头渲染器,批量生成速度比Matplotlib快,支持复杂绘图。

3. 多进程并行生成

利用多核CPU优势,通过multiprocessing拆分任务:

from multiprocessing import Pool
import matplotlib.pyplot as plt
from matplotlib.backends.backend_agg import FigureCanvasAgg as FigureCanvas

def generate_image(i):
    fig = plt.Figure(frameon=False, facecolor="white", figsize=(4, 4))
    ax = fig.add_subplot(111)
    ax.axis('off')
    ax.plot([1, 2, 3, 4, 5, 6, 7, 8], [2, 4, 6, 8, 8, 6, 4, 3])
    canvas = FigureCanvas(fig)
    canvas.print_figure(str(i), dpi=56)
    plt.close(fig)  # 关闭图形避免内存泄漏

if __name__ == '__main__':
    with Pool(processes=4) as pool:  # 进程数设为CPU核心数
        pool.map(generate_image, range(100))

注意:每个进程需独立创建图形对象,且及时关闭避免内存泄漏,总耗时可压缩至单进程的1/N左右(N为进程数)。

4. 优化图像保存流程

canvas.print_figure默认设置有冗余开销,可调整为:

import numpy as np
from PIL import Image

# 循环内生成图像后:
canvas.draw()
width, height = fig.get_size_inches() * fig.dpi
image_arr = np.frombuffer(canvas.tostring_rgb(), dtype='uint8').reshape(int(height), int(width), 3)
Image.fromarray(image_arr).save(f"{i}.png")

直接生成内存像素数据再用Pillow保存,比print_figure更高效;同时禁用bbox_inches='tight'等不必要参数,减少计算开销。

5. 硬件加速(可选)

若有GPU,可尝试:

  • TensorFlow绘图函数:直接在GPU上生成图像张量,写入TFRecord格式避免磁盘IO,适合深度学习训练场景。
  • CuPy加速:用CuPy替代NumPy处理数值计算,配合Matplotlib可小幅提升速度。

内容的提问来源于stack exchange,提问作者Alex Lach

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 18:48:38