1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【Python】mplfinance で複数グラフを描くとワーニング

Last updated at Posted at 2021-11-28

はじめに

株価データの分析のために,複数銘柄のチャートを描きたいと思った
例えば,TOPIX Core30 だと30銘柄ある
1銘柄ずつループで回していると,チャートは表示されるものの,ワーニングが表示される

/usr/local/lib/python3.9/site-packages/mplfinance/_mplwraps.py:60:
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`).
  f = plt.figure(FigureClass=Mpf_Figure,*args,**kwargs)

※本記事中,見やすさのため,出力結果の一部に改行をいれているところがあります

20個より多くのグラフを描くとワーニングになるようで,
このワーニングがでなくなる方法を備忘録として残しておく

ワーニングが出たコード

こちらのデータ(SPY_20110701_20120630_Bollinger.csv)を使って同じチャートを30回描くコードだ

warn_code.py
import pandas as pd
import mplfinance as mpf
df = pd.read_csv('SPY_20110701_20120630_Bollinger.csv',index_col=0,parse_dates=True)
# 30回チャートを描く
for index in range(30):
    # チャート描画
    fig = mpf.figure(figsize=(3, 3),style='yahoo')
    ax1 = fig.add_subplot(1,1,1)
    mpf.plot(df, ax=ax1, style='yahoo', type='candle', xrotation=30)

グラフは30個表示されるが,
mpl-error.png
上述のワーニングが表示される
image.png

問題解決のため調査をはじめる

このワーニングの対処法を調査すると,matplotlib の解決策ばかりだった

plt.clf()
plo.close()

matplotlib では clf と close を呼べばいいらしい
しかし,mplfinance の場合は,closeやclfがない
試しに読んでみると

>>> mpl.close()
AttributeError: module 'mplfinance' has no attribute 'close'
>>> mpl.clf()
AttributeError: module 'mplfinance' has no attribute 'clf'

モジュール内の一覧を表示してみると

>>> import mplfinance as mpl
>>> dir(mpl)
['__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__',
'__package__', '__path__', '__spec__', '__version__', '_arg_validators', '_helpers',
'_mpf_warnings', '_mplwraps', '_panels', '_styledata', '_styles', '_utils', '_version',
'_widths', 'available_styles', 'figure', 'make_addplot', 'make_marketcolors',
'make_mpf_style', 'mplfinance', 'plot', 'plotting', 'show', 'write_style_file']

確かになさそうだ
fig を作った plt を得るしかなさそうである

mplfinance のソースを見てみる

mplfinance.figure が定義されている,_mplwraps.py を見ると plt がいた

_mplwraps.py
def figure(*args,**kwargs):

    style = _check_for_and_apply_style(kwargs)

    f = plt.figure(FigureClass=Mpf_Figure,*args,**kwargs)
    f.mpfstyle = style
    return f

class Mpf_Figure(mplfigure.Figure):
    

matplotlib.pyplot.figure()関数を呼び出している

引数FigureClass=Mpf_FigureのMpf_Figureクラスは,_mplwraps.py 内で定義されているクラスだ

The wrapper function is the same as `matplotlib.pyplot.figure()`
except that it additionally accepts kwarg `style=` to set the mplfinance style.

_mplwraps.py のヘッダに書かれているが,mplfinance.figure()関数は基本 matplotlib.pyplot.figure()関数と同じだ
ただし,mplfinance の style を設定できるところだけが違う

style = _check_for_and_apply_style(kwargs)

_check_for_and_apply_style()関数で matplotlib.pyplot.figure()関数 に渡す kwargs から style を削除しているようだ

f.mpfstyle = style

そして,matplotlib.pyplot.figure()関数でできた mplfinance.figure に後からスタイルを設定している

解決案

matplotlib.pyplot と,mplfinance._mplwraps.Mpf_Figure をインポート

import matplotlib.pyplot as plt
import mplfinance as mpf
from mplfinance._mplwraps import Mpf_Figure

figure の生成を,mplfinance.figure()関数から,matplotlib.pyplot.figure()関数に変更する
style は後から設定してあげる

# もともとの figure 生成
fig = mpf.figure(figsize=(3, 3),style='yahoo')
# 新しい figure の生成方法
fig = plt.figure(FigureClass=Mpf_Figure,figsize=(3, 3))
fig.mpfstyle = 'yahoo'

plot が終わったら,clf と close を呼んであげる

plt.show()
plt.clf()
plt.close()

まとめると以下のようだ

ok_code.py
import pandas as pd
import matplotlib.pyplot as plt
import mplfinance as mpf
from mplfinance._mplwraps import Mpf_Figure
df = pd.read_csv('SPY_20110701_20120630_Bollinger.csv',index_col=0,parse_dates=True)
# 30回チャートを描く
for index in range(30):
    # チャート描画
    fig = plt.figure(FigureClass=Mpf_Figure,figsize=(3, 3))
    fig.mpfstyle = 'yahoo'
    ax1 = fig.add_subplot(1,1,1)
    mpf.plot(df, ax=ax1, style='yahoo', type='candle', xrotation=30)
    plt.show()
    plt.clf()
    plt.close()

mpl-error.png

めでたくワーニングが消えた

おわりに

matplotlib でのワーニングを消す方法を参考に mplfinance で行ってみた

うまいやり方,良い方法かどうかわからない…

これは違う,こうしたほうが良いなどあれば,コメントいただければと思う

追記

単にこれでよかったのかもしれない

インポートについて理解していなかったが,
Pythonのモジュールインポートのしくみを読むと,
モジュールオブジェクトはシングルトンなため,
自分で import した plt(matplotlib.pyplot)を使って clr,close を呼ぶだけ

# matplotlib.pyplot をインポート
import matplotlib.pyplot as plt

# plot,show の後に,pltのclf,closeを呼ぶ
plt.clf()
plt.close()

まとめると

ok_code2.py
import pandas as pd
import matplotlib.pyplot as plt
import mplfinance as mpf
df = pd.read_csv('SPY_20110701_20120630_Bollinger.csv',index_col=0,parse_dates=True)
# 30回チャートを描く
for index in range(30):
    # チャート描画
    fig = mpf.figure(figsize=(3, 3),style='yahoo')
    ax1 = fig.add_subplot(1,1,1)
    mpf.plot(df, ax=ax1, style='yahoo', type='candle', xrotation=30)
    plt.show()
    plt.clf()
    plt.close()
1
2
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?