チャートを証拠として残す!Pythonで株価グラフをPNG自動保存する方法

Python実装・コード

※本記事のコードや情報は執筆時点の仕様に基づいています。投資は自己責任であり、必ずデモ環境や少額資金でテストした上で運用してください。

Pythonで株価チャートを描画できるようになると、次に直面するのが「画像として保存したい」という要望です。

分析結果をSlackやDiscordに投稿したり、日次レポートとしてフォルダに蓄積したり、ブログ記事に挿入したりと、画像保存の用途は多岐にわたります。

しかし、matplotlibの plt.show() はあくまで画面表示用の関数であり、実行するとそこで処理がブロックされてしまいます。

自動化スクリプトの中に plt.show() を入れてしまうと、毎回手動でウィンドウを閉じないと次の処理に進めないという問題が発生します。

この記事では、matplotlib・mplfinanceを使って描画した株価チャートを、スクリプト実行時にPNG画像として自動保存する方法を解説します。

ローソク足チャート・テクニカル指標付きチャート・複数銘柄の一括保存まで、すべてコピペで動作するコードを提供します。

画像保存の基本 ― matplotlibのsavefig()を理解する

チャートの画像保存はすべて、matplotlibの savefig() メソッドが起点となります。

まずは基本的な使い方とパラメータを押さえてください。

savefig()の基本構文

matplotlibで描画したグラフを画像ファイルとして保存するには、plt.savefig() または fig.savefig() を使用します。

基本構文は以下の通りです。


import matplotlib.pyplot as plt

fig, ax = plt.subplots()
ax.plot([1, 2, 3], [4, 5, 6])

# 画像として保存
fig.savefig("output.png")
plt.close(fig)  # メモリ解放

plt.show() を呼ぶ前に savefig() を実行する点が重要です。

plt.show() の後に savefig() を呼ぶと、キャンバスがクリアされた状態で保存されるため、白紙の画像が出力されます。

savefig()の主要パラメータ

savefig() には描画品質やレイアウトを制御するパラメータが複数用意されています。

実務でよく使うものを以下の表にまとめます。

パラメータ 説明 推奨値
dpi 解像度(dots per inch) 150〜300(Web用は150、印刷用は300)
bbox_inches 余白の切り詰め設定 "tight"(余白を自動トリミング)
facecolor 背景色 "white"(透過させたくない場合)
transparent 背景を透過するか False(通常はFalse)
format 出力形式 "png" / "jpg" / "svg" / "pdf"
pad_inches bbox_inches="tight" 時の余白量 0.10.3

dpi=150bbox_inches="tight" の組み合わせは、Web掲載・チャット投稿用として最もバランスの良い設定です。迷ったらこの2つを指定してください。

plt.show()とsavefig()の使い分け

自動化スクリプトでは plt.show() を完全に削除し、savefig()plt.close() だけで運用するのが鉄則です。

理由を整理します。

  • plt.show():GUIウィンドウを表示し、ユーザーが閉じるまで処理がブロックされます
  • savefig():ファイルに書き出すだけなので、処理がブロックされません
  • plt.close():Figureオブジェクトを破棄し、メモリリークを防止します

複数銘柄のチャートをループで保存する場合、plt.close() を忘れるとメモリ使用量が際限なく増えていくため、必ずセットで使用してください。

【コピペOK】matplotlibで折れ線チャートを画像保存するコード

まずは、matplotlibの折れ線グラフ(終値チャート)を画像保存する基本パターンです。

yfinanceで株価データを取得し、PNGファイルとして出力します。

事前準備:ライブラリのインストール


pip install yfinance pandas matplotlib

【コピペOK】終値チャートのPNG保存コード


import yfinance as yf
import pandas as pd
import matplotlib.pyplot as plt
import os

# ==============================
# 設定エリア
# ==============================
SYMBOL = "7203.T"        # トヨタ自動車
PERIOD = "6mo"           # 取得期間(6ヶ月)
OUTPUT_DIR = "charts"    # 保存先フォルダ
DPI = 150                # 画像解像度

# ==============================
# 保存先フォルダの作成
# ==============================
os.makedirs(OUTPUT_DIR, exist_ok=True)

# ==============================
# データ取得
# ==============================
def fetch_data(symbol: str, period: str) -> pd.DataFrame:
    ticker = yf.Ticker(symbol)
    df = ticker.history(period=period)
    if df.empty:
        raise ValueError(f"{symbol} のデータを取得できませんでした。")
    return df

# ==============================
# チャート描画+画像保存
# ==============================
def save_line_chart(df: pd.DataFrame, symbol: str):
    ""終値の折れ線チャートをPNG画像として保存します。""
    fig, ax = plt.subplots(figsize=(12, 6))

    ax.plot(df.index, df["Close"], color="black", linewidth=1.2, label="Close")
    ax.fill_between(df.index, df["Close"], alpha=0.08, color="blue")

    ax.set_title(f"{symbol} - Close Price ({PERIOD})", fontsize=14)
    ax.set_ylabel("Price (JPY)", fontsize=11)
    ax.set_xlabel("Date", fontsize=11)
    ax.legend()
    ax.grid(True, alpha=0.3)

    # --- 画像保存 ---
    filepath = os.path.join(OUTPUT_DIR, f"{symbol.replace('.', '_')}_line.png")
    fig.savefig(filepath, dpi=DPI, bbox_inches="tight", facecolor="white")
    plt.close(fig)  # メモリ解放

    print(f"✔ 保存完了: {filepath}")

# ==============================
# メイン処理
# ==============================
if __name__ == "__main__":
    df = fetch_data(SYMBOL, PERIOD)
    save_line_chart(df, SYMBOL)

実行すると、charts フォルダの中に 7203_T_line.png が生成されます。

plt.show() を使わないため、スクリプトはチャートを表示することなく即座に終了します。

【コピペOK】mplfinanceでローソク足チャートを画像保存するコード

株式分析ではローソク足チャートの需要が非常に高いです。

ローソク足描画の定番ライブラリ「mplfinance」には、画像保存専用のパラメータが組み込まれています。

追加ライブラリのインストール


pip install mplfinance

mplfinanceはmatplotlibのラッパーライブラリであり、OHLCV(始値・高値・安値・終値・出来高)データを渡すだけで美しいローソク足チャートを自動生成できます。

【コピペOK】ローソク足+出来高+移動平均線の画像保存コード


import yfinance as yf
import mplfinance as mpf
import os

# ==============================
# 設定エリア
# ==============================
SYMBOL = "6758.T"         # ソニーグループ
PERIOD = "6mo"
OUTPUT_DIR = "charts"
DPI = 150

# ==============================
# 保存先フォルダの作成
# ==============================
os.makedirs(OUTPUT_DIR, exist_ok=True)

# ==============================
# データ取得
# ==============================
def fetch_data(symbol: str, period: str):
    ticker = yf.Ticker(symbol)
    df = ticker.history(period=period)
    if df.empty:
        raise ValueError(f"{symbol} のデータを取得できませんでした。")
    return df

# ==============================
# ローソク足チャート描画+画像保存
# ==============================
def save_candlestick_chart(df, symbol: str):
    ""mplfinanceでローソク足チャートを描画し、PNGとして保存します。""

    # カスタムスタイル
    custom_style = mpf.make_mpf_style(
        base_mpf_style="charles",
        rc={"font.size": 10},
    )

    filepath = os.path.join(OUTPUT_DIR, f"{symbol.replace('.', '_')}_candle.png")

    mpf.plot(
        df,
        type="candle",             # ローソク足
        style=custom_style,
        title=f"n{symbol} - Candlestick Chart",
        ylabel="Price (JPY)",
        volume=True,               # 出来高を表示
        mav=(5, 25),               # 移動平均線(5日・25日)
        figsize=(14, 8),
        savefig=dict(              # 画像保存設定
            fname=filepath,
            dpi=DPI,
            bbox_inches="tight",
            facecolor="white",
        ),
    )

    print(f"✔ 保存完了: {filepath}")

# ==============================
# メイン処理
# ==============================
if __name__ == "__main__":
    df = fetch_data(SYMBOL, PERIOD)
    save_candlestick_chart(df, SYMBOL)

mplfinanceでは savefig パラメータに辞書形式でファイルパスとオプションを渡します。

savefig を指定すると plt.show() は自動的にスキップされるため、自動化スクリプトとの相性が優れています。

mplfinanceの描画オプション一覧

mplfinanceの mpf.plot() で使用頻度の高いパラメータをまとめます。

  • type"candle"(ローソク足)、"ohlc"(バーチャート)、"line"(折れ線)
  • volumeTrue で出来高サブチャートを追加します
  • mav:タプルで複数の移動平均期間を指定できます(例:(5, 25, 75)
  • style"charles", "yahoo", "nightclouds" など組み込みスタイルが選択可能です
  • addplot:RSIやMACDなどのカスタム指標を追加パネルとして描画できます

【コピペOK】複数銘柄のチャートをループで一括保存するコード

実務では、監視銘柄のチャートを毎日まとめて画像保存するニーズが頻繁に発生します。

ここでは、for文でループしながら複数銘柄のローソク足チャートを一括生成するコードを紹介します。

【コピペOK】一括画像保存コード


import yfinance as yf
import mplfinance as mpf
import os
import time

# ==============================
# 設定エリア
# ==============================
SYMBOLS = [
    "7203.T",  # トヨタ自動車
    "6758.T",  # ソニーグループ
    "9984.T",  # ソフトバンクグループ
    "6861.T",  # キーエンス
    "8306.T",  # 三菱UFJフィナンシャル・グループ
]
PERIOD = "3mo"
OUTPUT_DIR = "charts_batch"
DPI = 150
SLEEP_SEC = 1.0

# ==============================
# 保存先フォルダの作成
# ==============================
os.makedirs(OUTPUT_DIR, exist_ok=True)

# ==============================
# 一括保存処理
# ==============================
def batch_save_charts():
    ""複数銘柄のローソク足チャートをPNG画像として一括保存します。""
    success_count = 0
    failed = []

    custom_style = mpf.make_mpf_style(
        base_mpf_style="charles",
        rc={"font.size": 9},
    )

    for i, symbol in enumerate(SYMBOLS, start=1):
        print(f"[{i}/{len(SYMBOLS)}] {symbol} を処理中...")

        try:
            ticker = yf.Ticker(symbol)
            df = ticker.history(period=PERIOD)

            if df.empty:
                print(f"  ⚠ {symbol}: データが空です。スキップします。")
                failed.append(symbol)
                continue

            filepath = os.path.join(
                OUTPUT_DIR, f"{symbol.replace('.', '_')}_candle.png"
            )

            mpf.plot(
                df,
                type="candle",
                style=custom_style,
                title=f"n{symbol}",
                volume=True,
                mav=(5, 25),
                figsize=(14, 8),
                savefig=dict(
                    fname=filepath,
                    dpi=DPI,
                    bbox_inches="tight",
                    facecolor="white",
                ),
            )

            print(f"  ✔ 保存完了: {filepath}")
            success_count += 1

        except Exception as e:
            print(f"  ✖ {symbol}: エラー → {e}")
            failed.append(symbol)

        if i < len(SYMBOLS):
            time.sleep(SLEEP_SEC)

    # --- 結果サマリー ---
    print("n========== 一括保存結果 ==========")
    print(f"成功: {success_count} 銘柄")
    print(f"失敗: {len(failed)} 銘柄 → {failed if failed else 'なし'}")

if __name__ == "__main__":
    batch_save_charts()

実行すると、charts_batch フォルダに各銘柄のローソク足チャートが個別PNGファイルとして保存されます。

このスクリプトをcron(Linux/Mac)やタスクスケジューラ(Windows)に登録すれば、毎日自動でチャート画像を蓄積する仕組みが構築できます。

ファイル名に日付を含めるテクニック

日次で画像を蓄積する場合、ファイルが上書きされないように日付をファイル名に含める方法が有効です。


from datetime import datetime

today = datetime.now().strftime("%Y%m%d")
filepath = os.path.join(OUTPUT_DIR, f"{symbol.replace('.', '_')}_{today}.png")
# 例: charts_batch/7203_T_20260223.png

この方法を使えば、過去のチャート画像を日付順に管理でき、後から相場の振り返りを行う際にも役立ちます。

よくあるエラーと対処法

チャートの画像保存で初心者がつまずきやすいポイントを解説します。

保存した画像が白紙(空白)になります

最も多い原因は、plt.show()savefig() の前に呼んでいることです。

plt.show() を実行するとFigureオブジェクトの内容がクリアされるため、その後の savefig() では空のキャンバスが保存されます。

対処法は以下の通りです。

  • plt.show() を完全に削除してください
  • savefig()plt.close() の順序で記述してください
  • mplfinanceの場合は savefig パラメータを指定するだけで show() は自動スキップされます

日本語フォントが「□□□」(豆腐文字)になります

matplotlibはデフォルトで日本語フォントを持っていません。

チャートのタイトルやラベルに日本語を使いたい場合は、japanize-matplotlib をインストールしてください。


pip install japanize-matplotlib

import japanize_matplotlib  # importするだけで日本語対応完了

このライブラリをimportするだけで、matplotlibが自動的に日本語対応フォント(IPAexゴシック)を使用するようになります。

メモリ不足で大量保存中にスクリプトが落ちます

ループ内で plt.close(fig) を呼び忘れると、Figureオブジェクトがメモリに蓄積され続けます。

100枚以上のチャートを生成する場合、数GBのメモリを消費することがあります。

ループ処理では必ず plt.close(fig) または plt.close("all") をループの末尾に配置してください。mplfinanceの savefig パラメータを使用する場合は自動的にcloseされるため、この問題は発生しません。

保存先フォルダが存在しないとエラーになります

savefig() は指定したディレクトリを自動作成しません。

事前に os.makedirs(OUTPUT_DIR, exist_ok=True) でフォルダを作成しておく必要があります。

exist_ok=True を付けることで、フォルダが既に存在する場合でもエラーを出さずにスキップできます。

まとめ

この記事では、Pythonで描画した株価チャートをPNG画像として自動保存する方法を、3つのパターンで解説しました。

要点を整理します。

  • matplotlibの fig.savefig() が画像保存の基本であり、dpi=150bbox_inches="tight" が推奨設定です
  • plt.show() は自動化スクリプトでは使用せず、savefig()plt.close() の組み合わせで運用してください
  • mplfinanceは savefig パラメータに辞書を渡すだけで、ローソク足チャートの画像保存が完結します
  • 複数銘柄のループ保存では、plt.close() によるメモリ解放と time.sleep() によるサーバー負荷軽減が不可欠です
  • ファイル名に日付を含めることで、日次チャート画像の自動蓄積が実現できます

次のステップとして、保存した画像をLINE NotifyやSlack Webhookで自動送信する仕組みを構築してみてください。

「データ取得 → 分析 → チャート描画 → 画像保存 → 通知送信」の一連のパイプラインが完成すれば、本格的な自動レポーティングシステムとして運用できます。

タイトルとURLをコピーしました