在Jupyter Notebook中使用Matplotlib批量绘图为何会耗尽RAM?
解决Matplotlib循环生成图片内存耗尽问题
针对你循环生成40000张图片时的内存耗尽问题——即便调用了plt.clf()和plt.close()仍未解决,核心原因是全局绘图状态的资源未彻底释放以及Pandas拼接操作的内存累积,可通过以下方法优化:
1. 显式管理Figure和Axes对象
别依赖Matplotlib的全局绘图接口(比如plt.matshow),显式创建Figure和Axes对象,确保每次循环都能彻底销毁资源:
- 用
plt.subplots()生成明确的图和轴对象 - 绘图完成后直接关闭对应的
Figure,而非依赖全局的plt.close()
2. 优化Pandas数据拼接逻辑
原代码每次循环都用pd.concat拼接小DataFrame,会产生大量临时对象,导致内存碎片和占用飙升。改为先把需要拼接的DataFrame收集到列表,最后一次性拼接,大幅减少内存开销。
3. 减少不必要的数据副本
避免创建冗余的DataFrame副本,比如直接在索引时获取所需数据,降低内存占用。
修改后的代码
import matplotlib.pyplot as plt import pandas as pd # 预提取AA中"One Letter"的映射,避免每次循环重复查询(可选但能显著提速) aa_mapping = {letter: df.iloc[:,1:] for letter, df in AA.groupby("One Letter")} for i in range(len(X_train)): tmp = X_train.iloc[i] # 用iloc更高效,避免loc的标签查询开销 # 收集需要拼接的数据块 df_list = [] for letter in range(1,5): target_letter = tmp[letter] # 直接从预映射中取数据,避免重复查询AA df_slice = aa_mapping[target_letter] df_list.append(df_slice) to_save = pd.concat(df_list, axis=0) # 显式创建Figure和Axes fig, ax = plt.subplots() ax.matshow(to_save, interpolation='none', vmin=0, vmax=1) ax.axis("off") # 关闭当前轴,而非全局plt.axis fig.savefig(f'D:/CNN/train/df_plot{i}.png', bbox_inches="tight") # 彻底销毁当前图对象 plt.close(fig)
额外优化建议
- 如果内存仍然紧张,可在每次循环末尾手动触发Python垃圾回收:
import gc gc.collect() - 检查
AA数据的类型,尽量用更节省内存的dtype(比如把字符串列转为category类型),减少每次查询和拼接的内存占用。
内容的提问来源于stack exchange,提问作者David
相关产品推荐
相关产品推荐

