2024-08-18

動的に複数のチャートを表示する

PySide (Qt for Python) は、Qt(キュート)の Python バインディングで、GUI などを構築するためのクロスプラットフォームなライブラリです。Linux/X11, macOS および Microsoft Windows をサポートしています。配布ライセンスは LGPL で公開されています。

mplfinance のチャートを PySide6 のウィジェットに埋め込んだ時に、表示するチャートを動的に増やしたり減らしたりしたかったので、FigureCanvas インスタンスを変えずに、表示するチャートの数を増減するサンプルを作ってみました。

下記の OS 環境で動作確認をしています。

RHEL 9.4 x86_64
Python 3.12.1
PySide6 6.7.2
mplfinance 0.12.10b0
yfinance 0.2.41

サンプルを以下に示しました。サンプルでは、日経平均株価の過去3ヶ月の日足データを yfinance で取得しています。

qt_mpl_finance_3.py
qt_mpl_finance_3.py の実行例

ツールバーの Volume チャックボックスにチェックを入れると、出来高の棒グラフが下に追加されます。プロットは切り替える度に再描画しています。

qt_mpl_finance_3.py の実行例(ツールバーの Volume チャックボックスをチェック)

FigureCanvas クラスを継承した MyChart クラスで、軸数の設定や再描画の処理をしています。今回の用途では縦方向にチャートを増減させるだけですが、メインのチャートを常に大きく表示したかったので、処理を簡単にするために GridSpec で複数チャートの表示レイアウトを決めています。

class MyChart(FigureCanvas):
    def __init__(self):
        self.fig = Figure()
        super().__init__(self.fig)
        self.fig.subplots_adjust(
            left=0.12,
            right=0.87,
            top=0.9,
            bottom=0.05,
        )
        self.ax = dict()

    def initAxes(self, ax, n: int):
        if n > 1:
            gs = self.fig.add_gridspec(
                n, 1,
                wspace=0.0, hspace=0.0,
                height_ratios=[3 if i == 0 else 1 for i in range(n)]
            )
            for i, axis in enumerate(gs.subplots(sharex='col')):
                ax[i] = axis
                ax[i].grid()
        else:
            ax[0] = self.fig.add_subplot()
            ax[0].grid()

    def initChart(self, n: int):
        self.removeAxes()
        self.initAxes(self.ax, n)

    def clearAxes(self):
        axs = self.fig.axes
        for ax in axs:
            ax.cla()

    def refreshDraw(self):
        self.fig.canvas.draw()

    def removeAxes(self):
        axs = self.fig.axes
        for ax in axs:
            ax.remove()
        self.ax = dict()

    def setTitle(self, title: str):
        self.ax[0].set_title(title)

MyChart の使い方は(mplfinance には依存せず)以下のような流れになります。

# MyChart クラスのインスタンスを配置
chart = MyChart()
self.setCentralWidget(chart)
# チャート用のナビゲーションツールバーを配置
navigation = NavigationToolbar(chart)
self.addToolBar(navigation)
...
...
# 表示するチャート数を n で指定して初期化
chart.initChart(n)

# チャートを描画
# 軸は chart.ax[0], chart.ax[1], ..., chart.ax[n-1] で指定
...
...

# チャートの表示を更新
chart.refreshDraw()
# ナビゲーションツールバーの更新
navigation.update()

参考サイト

  1. matplotlib.gridspec.GridSpec — Matplotlib documentation

 

ブログランキング・にほんブログ村へ bitWalk's - にほんブログ村 にほんブログ村 IT技術ブログ オープンソースへ
にほんブログ村

オープンソース - ブログ村ハッシュタグ
#オープンソース



このエントリーをはてなブックマークに追加

0 件のコメント: