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

2月 3, 2025

課題

mpfで連続してfigureを出力したときメモリエラーが出る

解決法

下記の関数のようにreturn_plot=Trueにし,plt.clf()とplt.close()をこの順番で入れる

from mplfinance._mplwraps import Mpf_Figure
def plot_candlestick_chart(self, head_number):
        # mpfでplt.close()を使うためには、Mpf_Figureを使う必要がある
        # https://qiita.com/tnozoo/items/776906392f9a4585c041
        fig = plt.figure(FigureClass=Mpf_Figure)
        fig.mpfstyle = 'yahoo'
        fig, ax = mpf.plot(
            self.stock_data, # 使用するデータフレームを第一引数に指定
            type='candle', # グラフ表示の種類を指定 ローソク足チャートであれば"candle"
            style='yahoo', # ここにスタイル一覧の中から好みのものを指定 例では"yahoo"を指定

            # チャートのサイズの設定
            figratio=(20, 10), # 図のサイズをタプルで指定
            figscale=1.0, # 図の大きさの倍率を指定、デフォルトは1
            tight_layout=True, # 図の端の余白を狭くして最適化するかどうかを指定

            # 軸の設定
            datetime_format='%Y/%m/%d', # X軸の日付の表示書式を指定
            # xlim=('2021-01-01', '2021-02-01'), # X軸の日付の範囲をタプルで指定 指定無しならデータフレームを元に自動で設定される
            # ylim=(25000, 30000), # Y軸の範囲をタプルで指定 指定無しなら自動で設定される
            xrotation=45, # X軸の日付ラベルの回転角度を指定 デフォルトは45度
            axisoff=False, # 軸を表示するかどうかを指定 デフォルトは"False"

            # データの表示設定
            volume=False, # ボリュームを表示するかどうかを指定 デフォルトは"False"
            show_nontrading=False, # データがない日付を表示するかどうかを指定 デフォルトは"False"

            # ラベルの設定
            # title=self.symbol, # チャートのタイトル
            ylabel='price', # チャートのY軸ラベル
            ylabel_lower='ylabel_lower', # ボリュームを表示する場合は、ボリュームのグラフのY軸ラベル

            # チャートの保存
            savefig=f'../output/{experiment_id}/{head_number}_{self.start_date}_to_{self.end_date}_{self.symbol}_candle.png',
            returnfig=True,
        )
        plt.clf()
        plt.close()

上記でもうまくいかず色々試した

色々やって警告は出るがプログラムは止まらなくなった.正直何が効いたかわからない

最初はノートブックで回していたが,スクリプト(.py)に変えてから調子が良くなった気も

plt.clfの後にplt.closeする順番は大事

plt.close('all’)もある

FigureManagerはオープン状態にして終わったらクローズするもの

mpfのオプションにreturnfig=Trueがある

class FigureManager:
    def __enter__(self):
        self.fig, self.ax = plt.subplots()
        return self.fig, self.ax

    def __exit__(self, exc_type, exc_val, exc_tb):
        # フィギュアが存在する場合に閉じる
        plt.close(self.fig)

def plot_candlestick_chart(self, head_number):
        with FigureManager() as (fig, ax):
            mpf.plot(
                self.stock_data, # 使用するデータフレームを第一引数に指定
                type='candle', # グラフ表示の種類を指定 ローソク足チャートであれば"candle"
                style='yahoo', # ここにスタイル一覧の中から好みのものを指定 例では"yahoo"を指定

                # チャートのサイズの設定
                figratio=(20, 10), # 図のサイズをタプルで指定
                figscale=1.0, # 図の大きさの倍率を指定、デフォルトは1
                tight_layout=True, # 図の端の余白を狭くして最適化するかどうかを指定

                # 軸の設定
                datetime_format='%Y/%m/%d', # X軸の日付の表示書式を指定
                # xlim=('2021-01-01', '2021-02-01'), # X軸の日付の範囲をタプルで指定 指定無しならデータフレームを元に自動で設定される
                # ylim=(25000, 30000), # Y軸の範囲をタプルで指定 指定無しなら自動で設定される
                xrotation=45, # X軸の日付ラベルの回転角度を指定 デフォルトは45度
                axisoff=False, # 軸を表示するかどうかを指定 デフォルトは"False"

                # データの表示設定
                volume=False, # ボリュームを表示するかどうかを指定 デフォルトは"False"
                show_nontrading=False, # データがない日付を表示するかどうかを指定 デフォルトは"False"

                # ラベルの設定
                # title=self.symbol, # チャートのタイトル
                ylabel='price', # チャートのY軸ラベル
                ylabel_lower='ylabel_lower', # ボリュームを表示する場合は、ボリュームのグラフのY軸ラベル

                # チャートの保存
                savefig=f'../output/{experiment_id}/{head_number}_{self.start_date}_to_{self.end_date}_{self.symbol}_candle.png',
                returnfig=True,
                # https://github.com/matplotlib/mplfinance/issues/131
                closefig=True,
                block=False,
            )

参考

https://qiita.com/tnozoo/items/776906392f9a4585c041

https://github.com/matplotlib/mplfinance/issues/131

Matplotlib,Python

Posted by vastee