Matplotlib批量生成千张2K分辨率图片速度过慢,求优化方案
优化Matplotlib批量生成图片的方法
问题描述
我希望在合理时间内生成1000张以上2K分辨率的图片,但目前用Matplotlib生成1000张图片需耗时2-3小时,想知道有没有优化Matplotlib的方法。
原始代码
data = file.read() iter = np.linspace(0,5000,5000).astype(int) hillshade = es.hillshade(data, azimuth=180, altitude=1) x_colormap = ListedColormap(newcolors) t = 0 for j in iter: data[data < j] = data.max() fig, ax = plt.subplots() fig.set_size_inches(6, 5) plt.imshow(data, cmap=x_colormap, norm=colors.LogNorm(1, data.max() - 1)) ax.imshow(hillshade, cmap="Greens", alpha=0.2) ax.axis('off') plt.show() plt.savefig(r'path', dpi=1200, bbox_inches="tight", pad_inches=0.0) t = t + 1 plt.close()
核心优化方案
- 删除交互式显示:直接去掉
plt.show(),这一步会触发GUI渲染,是批量生成时的冗余操作,会大幅拖慢速度。 - 复用画布与轴对象:把
fig, ax = plt.subplots()、fig.set_size_inches(6, 5)、ax.axis('off')移到循环外,循环内只更新图像内容,避免每次创建新画布的开销。 - 切换到非交互式后端:在代码开头添加
plt.switch_backend('Agg'),跳过GUI相关的渲染逻辑,减少资源占用。 - 避免修改原始数据:循环中
data[data < j] = data.max()会破坏原始数据,且每次修改数组开销大,改用临时数组:temp_data = np.where(data < j, data.max(), data),直接基于原数据生成临时副本。 - 匹配2K分辨率的参数设置:当前
dpi=1200+6x5英寸生成的是7200x6000像素的图,远超过2K(2560x1440)。直接设置fig.set_size_inches(2560/100, 1440/100)、dpi=100,精准生成2K图,避免不必要的高分辨率计算。 - 提前计算固定参数:
colors.LogNorm(1, data.max() - 1)中data.max()是固定值,提前计算好norm = colors.LogNorm(1, data.max() - 1),循环内直接复用。
优化后的代码示例
import matplotlib.pyplot as plt import numpy as np from matplotlib.colors import ListedColormap, LogNorm # 切换到非交互式后端 plt.switch_backend('Agg') data = file.read() iter_arr = np.linspace(0,5000,5000).astype(int) hillshade = es.hillshade(data, azimuth=180, altitude=1) x_colormap = ListedColormap(newcolors) # 提前计算固定参数 data_max = data.max() norm = LogNorm(1, data_max - 1) # 提前创建画布和轴,匹配2K分辨率 fig, ax = plt.subplots(figsize=(2560/100, 1440/100)) ax.axis('off') # 先绘制固定的hillshade图层 ax.imshow(hillshade, cmap="Greens", alpha=0.2) # 获取可更新的图像对象 im = ax.imshow(data, cmap=x_colormap, norm=norm) for idx, j in enumerate(iter_arr): # 生成临时数据,不修改原始data temp_data = np.where(data < j, data_max, data) # 更新图像数据 im.set_data(temp_data) # 保存图片,注意区分不同文件的路径 plt.savefig(f'output_{idx}.png', dpi=100, bbox_inches="tight", pad_inches=0.0) # 最后关闭画布释放资源 plt.close(fig)
额外提速建议
- 如果硬件支持,可尝试多进程并行生成图片(注意Matplotlib在多进程中需每个进程单独初始化后端),但要控制并发数量避免内存溢出。
- 对于简单的色彩映射和图层叠加,可改用
PIL/Pillow直接处理数组生成图片,其速度通常比Matplotlib更快。
内容的提问来源于stack exchange,提问作者Thomas Karl
相关产品推荐
相关产品推荐

