tkplotevent.py ライブラリ技術ドキュメント

ライブラリの機能や目的

tkplotevent.py は、matplotlib を使用して作成されたグラフに、インタラクティブなイベント処理機能を追加するためのPythonライブラリです。tkinter と連携してGUIアプリケーション内で matplotlib プロットを扱う際に、高度なユーザーインタラクション(マウス操作によるデータ選択、情報表示、範囲選択、オブジェクトの移動など)を容易に実装できるように設計されています。

このライブラリの主な機能は以下の通りです。

  • データポイントのインタラクティブな選択: マウスクリックにより、プロット上の最も近いデータポイントを特定し、その詳細情報をコンソールに表示します。

  • 範囲選択機能 (RangeSelector): マウスドラッグにより、X軸またはY軸、あるいはその両方にわたる選択範囲を視覚的に指定し、その範囲の座標値を取得できます。

  • 動的なアノテーション (mplcursors 連携): マウスカーソルをデータポイントに合わせると、そのデータに関する詳細情報がポップアップ表示される機能を提供します。

  • オブジェクトの移動: プロット上の特定のテキストアノテーションやデータポイントをマウスでドラッグして移動させることができます。

  • マウスカーソル追従表示: マウスカーソルの位置にクロスヘアライン(十字線)を表示し、X/Y軸上の現在位置を視覚的に示します。

  • カスタマイズ可能なポップアップメニュー: 右クリック時に表示されるコンテキストメニューを定義し、ユーザーが特定の操作を実行できるようにします。

  • ストップボタンの追加: プロットウィンドウに「停止」ボタンを追加し、長期実行されるプロセスをユーザーが中断できるようにします。

このライブラリは、科学技術計算やデータ分析の分野で、ユーザーがグラフから直接情報を取得したり、グラフの表示を操作したりする必要があるインタラクティブなデータ可視化ツールを開発する際に特に有用です。

importする方法

tkplotevent.py ライブラリを他のPythonプログラムからインポートするには、以下のステートメントを使用します。

from tkplotevent import tkPlotEvent, RangeSelector

または、すべての公開オブジェクトをインポートする場合は、以下のようにすることもできます。

import tkplotevent

必要な非標準ライブラリとインストール方法

tkplotevent.py は、以下の非標準ライブラリに依存しています。

  • numpy: 数値計算を効率的に行うためのライブラリ。

  • pandas: データ構造とデータ分析ツールを提供するライブラリ。

  • matplotlib: プロットとグラフ作成のためのライブラリ。

  • mplcursors: matplotlib のプロットにインタラクティブなデータカーソルとアノテーション機能を追加するライブラリ。

これらのライブラリは、通常 pip を使用してインストールできます。

pip install numpy pandas matplotlib mplcursors

tklib について: tkplotevent.py は、tklib.tkimport, tklib.tkobject, tklib.tkparams といったモジュールをインポートしています。これらは標準ライブラリではないため、tkplotevent.py が動作するためには、tklib というカスタムライブラリが別途インストールまたはPythonの環境パス上に配置されている必要があります。tklib は、matplotlibtkinter を組み合わせたGUIアプリケーション開発を支援するためのユーティリティ(ライブラリのインポート管理、基本的なオブジェクト、パラメータ管理など)を提供していると推測されます。tklib のインストール方法は、その配布方法に依存します。

importできる変数と関数

このライブラリからインポートできる主要なクラスとそのメソッドについて説明します。

クラス

RangeSelector クラス

プロット上でマウスドラッグによる範囲選択を可能にするクラスです。X軸、Y軸、または両方の範囲を選択できます。

コンストラクタ: __init__(self, mode = 'x', axis = None, color = 'red', linestyle = 'dashed', linewidth = 0.5, print_level = 1) 特定の matplotlib 軸に対して範囲選択機能を初期化します。

  • 引数:

    • mode (str, optional): 選択モードを指定します。「'x'」はX軸のみ、「'y'」はY軸のみ、「'xy'」は両軸を選択します。デフォルトは 'x'

    • axis (matplotlib.axes.Axes, optional): 範囲選択を行う対象の matplotlib 軸オブジェクト。デフォルトは None

    • color (str, optional): 選択範囲を示す線の色。デフォルトは 'red'

    • linestyle (str, optional): 選択範囲を示す線のスタイル。デフォルトは 'dashed'

    • linewidth (float, optional): 選択範囲を示す線の太さ。デフォルトは 0.5

    • print_level (int, optional): 選択範囲の情報をコンソールに出力するかどうか。1 で出力、0 で非出力。デフォルトは 1

  • 戻り値: なし

メソッド:

  • set_mode(self, mode) 選択モードを設定または変更します。

    • 引数:

      • mode (str): 新しい選択モード('x', 'y', 'xy')。

    • 戻り値: なし

  • on_press(self, event) マウスボタンが押されたときのイベントハンドラ。選択開始位置を記録し、仮の選択線を表示します。

    • 引数:

      • event (matplotlib.backend_bases.MouseEvent): マウスイベントオブジェクト。

    • 戻り値: なし

  • on_mouse_move(self, event) マウスが移動したときのイベントハンドラ。選択中の範囲をリアルタイムで更新し、表示します。

    • 引数:

      • event (matplotlib.backend_bases.MouseEvent): マウスイベントオブジェクト。

    • 戻り値: なし

  • on_release(self, event) マウスボタンが離されたときのイベントハンドラ。選択範囲を確定します。

    • 引数:

      • event (matplotlib.backend_bases.MouseEvent): マウスイベントオブジェクト。

    • 戻り値: なし

  • finalize(self) 選択範囲を確定し、コンソールに表示します。on_release から呼び出されます。

    • 引数: なし

    • 戻り値: なし

tkPlotEvent クラス

matplotlib のプロットに様々なインタラクティブイベント処理を追加するための中心的なクラスです。tklib.tkobject.tkObject を継承しています。

コンストラクタ: __init__(self, plt, distance = 'r', **args) イベントハンドラ機能を初期化します。

  • 引数:

    • plt (matplotlib.pyplot または Figure オブジェクト): matplotlib.pyplot モジュール、または Figure オブジェクト。

    • distance (str, optional): 最近接データを検索する際の距離の測り方を指定します。

      • 'r': 半径方向 (Euclidean distance)

      • 'x': X方向のみ

      • 'y': Y方向のみ デフォルトは 'r'

    • **args: tklib.tkobject.tkObject のコンストラクタに渡される追加引数。

  • 戻り値: なし

メソッド:

  • button_click(self, e) 汎用的なボタンクリックイベントのコールバック関数。内部の stop_flagTrue に設定します。

    • 引数:

      • e (matplotlib.widgets.Button イベントオブジェクト): ボタンイベントオブジェクト。

    • 戻り値: なし

  • finalize_button(self, text = 'finished') 追加されたボタンのテキストを更新します。

    • 引数:

      • text (str, optional): ボタンに表示する新しいテキスト。デフォルトは 'finished'

    • 戻り値: なし

  • add_button(self, button_region = [0.15, 0.95, 0.10, 0.03], plot_region = [0.92, 0.15], text = 'stop', color = '#f8e58c', hovercolor = '#38b48b', callback = None) プロットにクリック可能なボタンを追加します。

    • 引数:

      • button_region (list): ボタンの配置領域を [left, bottom, width, height] の形式で指定します(正規化された座標)。デフォルトは [0.15, 0.95, 0.10, 0.03]

      • plot_region (list): ボタンが追加された後のプロット領域を [top, bottom] の形式で指定します(正規化された座標)。デフォルトは [0.92, 0.15]

      • text (str, optional): ボタンに表示するテキスト。デフォルトは 'stop'

      • color (str, optional): ボタンの通常時の背景色。デフォルトは '#f8e58c'

      • hovercolor (str, optional): マウスカーソルがボタン上にあるときの背景色。デフォルトは '#38b48b'

      • callback (callable, optional): ボタンがクリックされたときに呼び出される関数。デフォルトは self.button_click

    • 戻り値: matplotlib.widgets.Button オブジェクト。

  • layout(self, show = False) プロットのレイアウトを調整します。

    • 引数:

      • show (bool, optional): プロットを表示するかどうか。True の場合、plt.show() または plt.pause() が呼び出されます。デフォルトは False

    • 戻り値: なし

  • remove(self, index) 追加されたデータセットを削除します。

    • 引数:

      • index (int or str): 削除するデータセットのインデックス(数値)またはラベル(文字列)。

    • 戻り値: なし

  • add_stop_button(self, button_region = [0.15, 0.95, 0.10, 0.03], plot_region = [0.92, 0.15], label = 'stop', color = '#f8e58c', hovercolor = '#38b48b', on_stop_clicked = None) プロットにストップボタンを追加します。このボタンは内部で tkStopButton クラスを使用し、クリック時にステータスを「stop」に変更し、ターミナルにメッセージを出力します。

    • 引数:

      • button_region (list): ボタンの配置領域。デフォルトは [0.15, 0.95, 0.10, 0.03]

      • plot_region (list): プロット領域の調整に使うパラメータ。デフォルトは [0.92, 0.15]

      • label (str, optional): ボタンに表示するテキスト。デフォルトは 'stop'

      • color (str, optional): ボタンの通常時の背景色。デフォルトは '#f8e58c'

      • hovercolor (str, optional): ホバー時の背景色。デフォルトは '#38b48b'

      • on_stop_clicked (callable, optional): ストップボタンがクリックされたときに呼び出されるカスタム関数。デフォルトは内部で定義された処理。

    • 戻り値: なし

  • add_data(self, axis_inf = {}) プロットイベント処理の対象となるデータを登録します。データは内部で統一された形式に変換されます。

    • 引数:

      • axis_inf (dict): データに関する情報を含む辞書。必須キーは 'plot_type' ('2D', 'plot', 'scatter')、'axis' (matplotlib.axes.Axes オブジェクト)、'data' (Line2D オブジェクトまたは散布図データ)。

    • 戻り値: 登録された axis_inf 辞書。

  • find_target_axes(self, event, axes = None) マウスイベントが発生した軸を特定します。

    • 引数:

      • event (matplotlib.backend_bases.MouseEvent): マウスイベントオブジェクト。

      • axes (list of matplotlib.axes.Axes, optional): 検索対象の軸のリスト。指定されない場合、self.axis_inf に登録された軸が使用されます。

    • 戻り値:

      • itargets (int or list of int): 特定された軸のインデックス、またはインデックスのリスト。

      • hit_axisinfs (matplotlib.axes.Axes or list of matplotlib.axes.Axes): 特定された軸オブジェクト、または軸オブジェクトのリスト。

      • ターゲットが見つからない場合は (None, None)

  • convert_coord(self, x0, y0, axis_s, axis_t) ある軸の座標を別の軸の座標に変換します。twinx()twiny() で作成された軸間で座標を変換する際に使用されます。

    • 引数:

      • x0, y0 (float): 変換元の軸 (axis_s) でのX, Y座標。

      • axis_s (matplotlib.axes.Axes): 変換元の軸オブジェクト。

      • axis_t (matplotlib.axes.Axes): 変換先の軸オブジェクト。

    • 戻り値:

      • x1, y1 (float): 変換先の軸 (axis_t) でのX, Y座標。

      • いずれかの引数が None の場合 (None, None)

  • prepare_popup_menu(self, fig, parent = None) 右クリック時に表示されるポップアップメニューを準備します。

    • 引数:

      • fig (matplotlib.figure.Figure): ポップアップメニューに関連付ける Figure オブジェクト。

      • parent (tkinter.Tk or tkinter.Toplevel, optional): Tkinterの親ウィンドウ。指定しない場合、非表示のルートウィンドウが作成されます。デフォルトは None

    • 戻り値: なし

    • 追加メソッド: self.popup_menu.add_menu(label, command) を使用してメニュー項目を追加できます。

  • register_popup_menu_event(self, on_click = None) ポップアップメニュー表示のための右クリックイベントを登録します。

    • 引数:

      • on_click (callable, optional): カスタムの右クリックイベントハンドラ。デフォルトはライブラリ内部で定義された関数。

    • 戻り値: なし

  • prepare_move_points(self) プロット上のデータポイントを移動させる機能の準備を行います。

    • 引数: なし

    • 戻り値: なし

    • 追加メソッド: self.move_points.add(ax, x, y, marker, picker, color) を使用して移動可能な点を追加できます。

  • prepare_move_text(self, fig = None) プロット上のテキストやアノテーションを移動させる機能の準備を行います。

    • 引数:

      • fig (matplotlib.figure.Figure, optional): 移動対象のテキストが含まれる Figure オブジェクト。

    • 戻り値: なし

    • 追加メソッド: self.move_text.add_text(...) および self.move_text.add_annotation(...) を使用して移動可能なテキスト/アノテーションを追加できます。

  • register_move_text_event(self, fig = None, activate = False) テキストやアノテーションを移動させるためのイベントを登録します。

    • 引数:

      • fig (matplotlib.figure.Figure, optional): イベントを登録する Figure オブジェクト。

      • activate (bool, optional): 初期状態で移動機能を有効にするかどうか。デフォルトは False

    • 戻り値: なし

    • 追加メソッド: self.move_text.activate(flag) を使用して移動機能の有効/無効を切り替えられます。

  • register_move_points_event(self, fig) データポイントを移動させるためのイベントを登録します。

    • 引数:

      • fig (matplotlib.figure.Figure): イベントを登録する Figure オブジェクト。

    • 戻り値: なし

  • prepare_annotation(self) mplcursors を使用した動的なアノテーション機能の準備を行います。

    • 引数: なし

    • 戻り値: なし

    • 追加メソッド: self.annotation.add_line(...) を使用してアノテーション対象のラインデータを登録できます。

  • register_annotation_event(self, fig, activate = True, on_mouse_move = None, on_click = None, print_level = 0) mplcursors を使用したアノテーション機能、およびマウスクリック時の情報表示イベントを登録します。

    • 引数:

      • fig (matplotlib.figure.Figure): イベントを登録する Figure オブジェクト。

      • activate (bool, optional): 初期状態でアノテーション機能を有効にするかどうか。デフォルトは True

      • on_mouse_move (callable, optional): カスタムのマウス移動イベントハンドラ。デフォルトは内部で定義された関数。

      • on_click (callable, optional): カスタムのマウスクリックイベントハンドラ。デフォルトは内部で定義された関数。

      • print_level (int, optional): mplcursors による情報表示のレベル。デフォルトは 0

    • 戻り値: なし

    • 追加メソッド: self.annotation.activate(flag) を使用してアノテーション機能の有効/無効を切り替えられます。また、self.annotation.refresh_cursors() でカーソルを再初期化できます。

  • register_follow_mouse_event(self, fig, activate = True, on_mouse_move = None, print_level = 0) マウスカーソル追従表示(クロスヘアなど)のためのイベントを登録します。

    • 引数:

      • fig (matplotlib.figure.Figure): イベントを登録する Figure オブジェクト。

      • activate (bool, optional): 初期状態で追従機能を有効にするかどうか。デフォルトは True

      • on_mouse_move (callable, optional): カスタムのマウス移動イベントハンドラ。デフォルトは内部で定義された関数。

      • print_level (int, optional): デバッグ出力のレベル。デフォルトは 0

    • 戻り値: なし

    • 追加メソッド: self.follow_mouse.add(ax, line, width, marker, size, color) を使用して追従表示を行う軸とスタイルを追加できます。self.follow_mouse.activate(flag) で有効/無効を切り替えられます。

  • register_event(self, fig, event = "button_press_event", callback = None) 指定された matplotlib イベントに対して汎用的なコールバック関数を登録します。

    • 引数:

      • fig (matplotlib.figure.Figure): イベントを登録する Figure オブジェクト。

      • event (str, optional): 登録するイベント名(例: 'button_press_event', 'motion_notify_event', 'key_press_event')。デフォルトは 'button_press_event'

      • callback (callable, optional): イベント発生時に呼び出される関数。デフォルトは self.onclick

    • 戻り値: なし

  • register_click(self, fig, event = "button_press_event", callback = None) マウスクリックイベントを登録します。register_event のラッパーです。

    • 引数:

      • fig (matplotlib.figure.Figure): イベントを登録する Figure オブジェクト。

      • event (str, optional): イベント名。デフォルトは 'button_press_event'

      • callback (callable, optional): コールバック関数。デフォルトは self.onclick

    • 戻り値: なし

  • register_pick(self, fig, event = "pick_event", callback = None) オブジェクトのピックイベントを登録します。register_event のラッパーです。

    • 引数:

      • fig (matplotlib.figure.Figure): イベントを登録する Figure オブジェクト。

      • event (str, optional): イベント名。デフォルトは 'pick_event'

      • callback (callable, optional): コールバック関数。デフォルトは self.onpick

    • 戻り値: なし

  • register_redraw(self, fig, event = "draw_event", callback = None) 再描画イベントを登録します。register_event のラッパーです。

    • 引数:

      • fig (matplotlib.figure.Figure): イベントを登録する Figure オブジェクト。

      • event (str, optional): イベント名。デフォルトは 'draw_event'

      • callback (callable, optional): コールバック関数。デフォルトは self.ondraw

    • 戻り値: なし

  • register_key(self, fig, event = "key_press_event", callback = None) キーボード押下イベントを登録します。register_event のラッパーです。

    • 引数:

      • fig (matplotlib.figure.Figure): イベントを登録する Figure オブジェクト。

      • event (str, optional): イベント名。デフォルトは 'key_press_event'

      • callback (callable, optional): コールバック関数。デフォルトは self.onkey

    • 戻り値: なし

  • onkey(self, event) デフォルトのキーボード押下イベントハンドラ。'q' キーが押されるとプロットウィンドウを閉じます。

    • 引数:

      • event (matplotlib.backend_bases.KeyEvent): キーイベントオブジェクト。

    • 戻り値: なし

  • onclick(self, event) デフォルトのマウスクリックイベントハンドラ。クリックされた位置に最も近いデータポイントを検索し、その情報をコンソールに表示します。

    • 引数:

      • event (matplotlib.backend_bases.MouseEvent): マウスイベントオブジェクト。

    • 戻り値: なし

  • onpick(self, event) デフォルトのオブジェクトピックイベントハンドラ。クリックされたオブジェクトのラベルをコンソールに表示します。

    • 引数:

      • event (matplotlib.backend_bases.PickEvent): ピックイベントオブジェクト。

    • 戻り値: なし

  • ondraw(self, event) デフォルトの再描画イベントハンドラ。現在、コンソールに「draw」と出力するのみです。

    • 引数:

      • event (matplotlib.backend_bases.DrawEvent): 描画イベントオブジェクト。

    • 戻り値: なし

  • find_nearest_data(self, x, y, itarget_list, hit_axisinf_list) 指定された座標 \((x, y)\) に最も近いデータポイントを検索します。

    • 引数:

      • x, y (float): 検索するX, Y座標。

      • itarget_list (list of int): 検索対象となる軸のインデックスのリスト。

      • hit_axisinf_list (list of dict): 検索対象となる軸情報辞書のリスト。

    • 戻り値:

      • iinf_hit (int): 最も近いデータポイントが見つかった軸情報のインデックス。

      • idata_hit (int): その軸情報内のデータ系列のインデックス。

      • ihit (int): そのデータ系列内のデータポイントのインデックス。

      • minr2 (float): 最も近いデータポイントまでの正規化された距離の二乗。

      • データが見つからない場合は (None, None, None, None)

  • display_data(self, iinf, idata, idx, hit_axisinf = None) 最も近いデータポイントの詳細情報をコンソールに表示します。

    • 引数:

      • iinf (int): 軸情報のインデックス。

      • idata (int): データ系列のインデックス。

      • idx (int): データポイントのインデックス。

      • hit_axisinf (dict, optional): 表示する軸情報辞書。指定しない場合、self.axis_inf[iinf] が使用されます。

    • 戻り値: なし

main scriptとして実行したときの動作

tkplotevent.py ライブラリは、直接スクリプトとして実行された場合の特定の動作は定義されていません。つまり、if __name__ == "__main__": ブロックが存在しないため、このファイルを直接実行しても、特別なデモやテストコードは実行されません。このライブラリは、他のPythonスクリプトからインポートされ、その機能が利用されることを前提としています。