如何在Matplotlib中保存并复用绘图,避免重复计算资源密集型等高线图?
解决内存不足导致的等高线网格生成崩溃问题
核心思路
你的问题本质是一次性加载4个高资源消耗的绘图实例,导致内存溢出。解决方向是避免同时持有多个高内存占用的绘图对象,要么逐个生成后转存为轻量格式再组合,要么提取核心数据后重新绘制。
方法1:逐个生成并保存为图像,再组合到网格
适合无法从自定义包获取底层数据的场景,通过临时文件中转,彻底释放单个绘图的内存:
- 逐个生成并保存单图,生成后立即清理内存:
import matplotlib.pyplot as plt import gc # 生成第一个图并保存 plt.figure() plt.contourf(blah blah) # 替换为你的自定义包绘图代码 plt.savefig("plot00.png") plt.close() # 关闭当前画布释放内存 gc.collect() # 强制触发垃圾回收 # 重复生成其余三个图,分别存为plot10.png、plot01.png、plot11.png plt.figure() plt.contourf(blah blah) plt.savefig("plot10.png") plt.close() gc.collect() plt.figure() plt.contourf(blah blah) plt.savefig("plot01.png") plt.close() gc.collect() plt.figure() plt.contourf(blah blah) plt.savefig("plot11.png") plt.close() gc.collect()
- 创建2x2网格,加载并显示保存的图像:
from PIL import Image import numpy as np fig, axs = plt.subplots(2, 2) # 加载图像并显示,关闭坐标轴保持原绘图样式 img00 = np.array(Image.open("plot00.png")) axs[0,0].imshow(img00) axs[0,0].axis('off') img10 = np.array(Image.open("plot10.png")) axs[1,0].imshow(img10) axs[1,0].axis('off') img01 = np.array(Image.open("plot01.png")) axs[0,1].imshow(img01) axs[0,1].axis('off') img11 = np.array(Image.open("plot11.png")) axs[1,1].imshow(img11) axs[1,1].axis('off') plt.tight_layout() plt.show()
方法2:提取绘图数据后重新绘制(优先尝试)
如果能从自定义包的contourf中拿到核心数据(网格坐标、高度值),直接用matplotlib原生函数绘制,内存占用会大幅降低:
- 逐个获取并保存绘图数据:
import matplotlib.pyplot as plt import gc plot_data = [] # 获取第一个图的数据(假设自定义包的contourf返回带X/Y/Z属性的对象) plt.figure() contour_obj = custom_package.contourf(blah blah) plot_data.append( (contour_obj.X, contour_obj.Y, contour_obj.Z) ) plt.close() gc.collect() # 重复获取其余三个图的数据 plt.figure() contour_obj = custom_package.contourf(blah blah) plot_data.append( (contour_obj.X, contour_obj.Y, contour_obj.Z) ) plt.close() gc.collect() # 剩下两个图同理...
- 用matplotlib原生函数绘制网格:
fig, axs = plt.subplots(2, 2) # 逐个绘制数据 axs[0,0].contourf(plot_data[0][0], plot_data[0][1], plot_data[0][2]) axs[1,0].contourf(plot_data[1][0], plot_data[1][1], plot_data[1][2]) axs[0,1].contourf(plot_data[2][0], plot_data[2][1], plot_data[2][2]) axs[1,1].contourf(plot_data[3][0], plot_data[3][1], plot_data[3][2]) plt.tight_layout() plt.show()
方法3:生成单个子图后立即清理资源(简易版)
如果不想保存文件,可尝试在生成每个子图后强制回收内存,但效果取决于自定义包的内存管理:
fig, axs = plt.subplots(2, 2) # 生成第一个子图后清理 axs[0,0].contourf(blah blah) plt.draw() # 强制绘制当前子图 gc.collect() # 回收闲置内存 # 生成第二个子图后清理 axs[1,0].contourf(blah blah) plt.draw() gc.collect() # 剩下两个子图同理... plt.show()
内容的提问来源于stack exchange,提问作者quantum_loser
相关产品推荐
相关产品推荐

