以下是源代码,结果:function里有个for循环,在每一次循环都有plt.close(),但是还是报错:
def generate_plot(self, sn, df_data, df_limiter, file_path):
"""
Generate the plot picture and fig data by pandas.DataFrame
todo: need control the max min points.
"""
plt.figure(figsize=(figsize_width, figsize_hight)) # type: plt.figure.Figure
ax=df_data.plot() # type: pd.plotting._core.FramePlotMethods
df_limiter.plot(ax=ax, c='r',legend=False)
plt.grid(True, which="both", ls="-")
plt.title(sn + "fail_rate_des", fontdict={'fontsize': 1})
plt.xlabel('Frequency(Hz)', fontsize=1)
plt.ylabel('(dB)', fontsize=1)
plt.xscale('log') # Used to resolve x scale
plt.yscale('linear')
plt.tight_layout()
# plt.legend(loc=0)
plt.minorticks_on()
plt.savefig(file_path)
plt.close()
def f():
for ...
self.generate_plot(.....)
调试的时候发现是: 创建的ax对象一直是同一个,plt.close并没有重置它。
如果你创建了太多的 figure, 对象,你会收到这个警告。
使用以下代码,能清除并且关闭掉 figure 对象。
plt.cla()
plt.close("all")
如果你需要画很多图,这样频繁的 “创建→清除” 是会拖慢你的代码运行速度的。最好的办法是,只创建一个 figure 对象,在画下一个图之前,使用 plt.cla() 清理掉 axes,这样可以复用 figure。
一种情况是
第一个情况是:我同时执行.clf(), .cla()。 删除plt.clf()即可。
plt.clf()
plt.cla()
# plt.close()
在for循环外创建figure,ax对象,
每次生成图片的时候plt.cla()执行一次清除,
最后for循环外plt.close("all")
#
def generate_plot(self, sn, df_data, df_limiter, file_path):
"""
Generate the plot picture and fig data by pandas.DataFrame
todo: need control the max min points.
"""
df_data.plot(ax=self.ax) # type: pd.plotting._core.FramePlotMethods
df_limiter.plot(ax=self.ax, c='r',legend=False)
plt.grid(True, which="both", ls="-")
plt.title(sn + "fail_rate_des", fontdict={'fontsize': 1})
plt.xlabel('Frequency(Hz)', fontsize=1)
plt.ylabel('(dB)', fontsize=1)
plt.xscale('log') # Used to resolve x scale
plt.yscale('linear')
plt.tight_layout()
# plt.legend(loc=0)
plt.minorticks_on()
plt.savefig(file_path)
plt.cla()
#plt.close()
def f():
self.fig, self.ax = plt.subplots()
for ...
self.generate_plot(.....)
plt.close("all")
一共是生成24个图片,大概1900个数据点。加速之前是:13.269s, 加速之后基本在12.2s左右,快了1s。
以上加速,如要生成self.fig,用xlwings 这个库把self.fig插入excel会出现,plt.clf(), plt.cla()都失效,图片会重复叠加在最后一张图。
以下是解决插入excel图片重叠生成在一个图片上问题,还是得每次创建一次fig,然后再plot,不能用全局fig.
fig,ax=plt.subplots(clear=True)
df_data.plot(ax=ax) # type: pd.plotting._core.FramePlotMethods
df_limiter.plot(ax=ax, c='r', legend=False)
plt.grid(True, which="both", ls="-")
plt.title(sn + "fail_rate_des", fontdict={'fontsize': 5})
plt.xlabel('Frequency(Hz)', fontsize=5)
plt.ylabel('(dB)', fontsize=5)
plt.xscale('log') # Used to resolve x scale
plt.yscale('linear')
plt.tight_layout()
plt.minorticks_on()
plt.savefig(file_path) # 保存到图片
self.tp.update_xlsx_by_sn(sn, fig) # save to excel
plt.cla()
# self.tp.update_xlsx_by_sn()主要是执行插入图片:
self.sheet.pictures.add(fig, left=self.sheet.range(cell_value).left,top=self.sheet.range(cell_value).top) # 在G2单元格插入
RuntimeWarning: More than 20 figures have been opened. Figures created through the pyplot interface (
matplotlib.pyplot.figure
) are retained until explicitly closed and may consume too much memory. (To control this warning, see the rcParamfigure.max_open_warning
).
max_open_warning, RuntimeWarning)
If you intend to knowingly keep many plots in memory, but don't want to be warned about it, you can update your options prior to generating figures.
plt.rcParams.update({'figure.max_open_warning': 0})
plt.cla()
# clear a axisplt.clf()
# clear the entire current figure with all its axes, but leaved the window opened, such that it may be reused for other plots;plt.close()
# close the window,which will be the current window,plt.close('all')
will close all open figures