Pandas RuntimeWarning: More than 20 figures have been opened. Figures created plt.close()也不起作用

以下是源代码,结果:function里有个for循环,在每一次循环都有plt.close(),但是还是报错:

More than 20 figures have been opened. Figures created 

    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.close("all"),关闭所有 

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 rcParam figure.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 axis
plt.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

你可能感兴趣的:(python,python,matplotlib)