"""
MatplotlibのプロットをTkinterアプリケーションに統合するためのユーティリティクラスを提供します。
このモジュールは、MatplotlibのFigureをTkinterウィンドウに埋め込み、表示を管理するための
`tkPlot_tkinter` クラスを定義します。Matplotlibの基本的なプロット機能と、
TkinterベースのGUI操作を組み合わせることができます。
:doc:`tkplot_tkinter_usage`
"""
import tklib.tkimport as imp
numpy = imp.import_lib("numpy", stop_by_error = False)
mpl = imp.import_lib("matplotlib", stop_by_error = False)
mplcursors = imp.import_lib("mplcursors", stop_by_error = False)
tk = imp.import_lib("tkinter", stop_by_error = False)
from tkinter import Tk, Menu
from tkinter import ttk
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
from matplotlib.figure import Figure
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2Tk
imp.messages(stop_by_error = False)
from tklib.tkobject import tkObject
from tklib.tkparams import tkParams
[ドキュメント]
class tkPlot_tkinter(tkObject):
"""
MatplotlibのプロットをTkinterウィンドウに埋め込み、表示を管理するクラスです。
このクラスはtkObjectを継承し、MatplotlibのFigureをTkinterのキャンバスに表示するための
基本的な機能と、Matplotlibの主要な関数をラップするメソッドを提供します。
ユーザーは、このクラスを使ってMatplotlibのプロットをTkinterアプリケーションに
シームレスに統合できます。
"""
def __init__(self, plt, parent = None, title = None):
"""
tkPlot_tkinterクラスの新しいインスタンスを初期化します。
:param plt: Matplotlibのpyplotモジュール、またはそれに準ずるオブジェクト。
:type plt: module
:param parent: プロットを表示する親Tkinterウィジェット。Noneの場合、新しいTkinterルートウィンドウが作成されます。
:type parent: tkinter.Tk or tkinter.Widget or None
:param title: Tkinterウィンドウのタイトル。親ウィジェットが指定されている場合はそのタイトルを設定します。
新しいルートウィンドウが作成された場合、そのウィンドウのタイトルになります。
:type title: str or None
"""
self.plt = plt
self.canvas = None
if parent is None:
self.parent = tk.Tk()
else:
self.parent = parent
if title:
parent.title(title)
[ドキュメント]
def create_window(self, fig):
"""
プロット表示用のウィンドウをセットアップします。
現在はツールバーの追加のみを行います。将来的にウィンドウの構成要素を追加する際に使用されます。
:param fig: 表示するMatplotlibのFigureオブジェクト。
:type fig: matplotlib.figure.Figure
:returns: なし
:rtype: None
"""
self.add_toolbar()
# self.add_toolbar_button(text = "test")
# self.update()
[ドキュメント]
def update(self):
"""
MatplotlibキャンバスとTkinterウィンドウを更新します。
キャンバスが存在する場合は再描画し、その後Tkinterのイベントループを更新します。
これにより、プロットやGUI要素の変更が即座に反映されます。
:returns: なし
:rtype: None
"""
if self.canvas:
self.canvas.draw()
self.parent.update()
[ドキュメント]
def show(self):
"""
プロットを表示し、ウィンドウを更新します。
内部的には `update` メソッドを呼び出し、最新のプロット状態を反映させます。
これは、プロットの初期表示や、変更後の表示更新に使用されます。
:returns: なし
:rtype: None
"""
self.update()
[ドキュメント]
def pause(self, t):
"""
プロットを更新し、指定された時間だけ一時停止します。
このメソッドは、アニメーションや逐次的なプロット更新において、
各フレーム間の間隔を設けるのに役立ちます。
:param t: 一時停止する時間(秒)。
:type t: float
:returns: なし
:rtype: None
"""
self.update()
self.plt.pause(t)
[ドキュメント]
def draw(self):
"""
プロットを再描画します。
内部的には `update` メソッドを呼び出します。
これは、Matplotlibの `plt.draw()` に相当する機能を提供し、
キャンバスの内容を更新します。
:returns: なし
:rtype: None
"""
# self.plt.draw()
# self.canvas.draw()
self.update()
[ドキュメント]
def get_current_fig_manager(self):
"""
Matplotlibの現在のFigureManagerを取得します。
このマネージャーは、Figureのウィンドウやイベントハンドリングを管理します。
:returns: 現在のFigureManagerオブジェクト。
:rtype: matplotlib.backend_bases.FigureManagerBase
"""
return self.plt.get_current_fig_manager()
[ドキュメント]
def tight_layout(self, **kwargs):
"""
Figureのサブプロットパラメータを自動的に調整し、要素間のパディングをタイトにします。
Matplotlibの `plt.tight_layout()` をラップします。
プロットのタイトル、ラベル、凡例などが重なり合うのを防ぐのに役立ちます。
:param kwargs: `plt.tight_layout()` に渡される追加のキーワード引数。
:returns: なし
:rtype: None
"""
return self.plt.tight_layout(**kwargs)
[ドキュメント]
def subplots_adjust(self, **kwargs):
"""
サブプロットのレイアウトパラメータを手動で調整します。
Matplotlibの `plt.subplots_adjust()` をラップします。
サブプロット間のスペースや余白を細かく制御したい場合に使用します。
:param kwargs: `plt.subplots_adjust()` に渡される追加のキーワード引数(例: left, right, bottom, top, wspace, hspace)。
:returns: なし
:rtype: None
"""
return self.plt.subplots_adjust(**kwargs)
[ドキュメント]
def axes(self, *args, **kwargs):
"""
現在のFigureに新しいAxesを追加するか、既存のAxesを現在のAxesに設定します。
Matplotlibの `plt.axes()` をラップします。
これにより、特定の座標系(Axes)に対してプロットコマンドを実行できます。
:param args: `plt.axes()` に渡される位置引数。
:param kwargs: `plt.axes()` に渡されるキーワード引数。
:returns: 作成または設定されたAxesオブジェクト。
:rtype: matplotlib.axes.Axes
"""
return self.plt.axes(*args, **kwargs)
[ドキュメント]
def subplots(self, ny, nx, figsize = (8, 6), dpi = 100, tight_layout = True, **kwargs):
"""
複数のサブプロットを持つFigureを作成します。
指定された行数(ny)と列数(nx)に基づいてサブプロットを配置し、それらを内部リストに格納します。
作成されたFigureとAxesのリストを返します。
`tight_layout` がTrueの場合、制約付きレイアウトが有効になり、サブプロットの配置が自動調整されます。
:param ny: サブプロットの行数。
:type ny: int
:param nx: サブプロットの列数。
:type nx: int
:param figsize: Figureのサイズ(幅、高さ)をインチで指定。
:type figsize: tuple[int, int]
:param dpi: Figureの解像度(ドット/インチ)。
:type dpi: int
:param tight_layout: レイアウトを自動調整するかどうか。Trueの場合、`fig.set_constrained_layout(True)` が設定されます。
:type tight_layout: bool
:param kwargs: `fig.add_subplot()` に渡される追加のキーワード引数。
:returns: (Figureオブジェクト, Axesオブジェクトのリスト) のタプル。
:rtype: tuple[matplotlib.figure.Figure, list[matplotlib.axes.Axes]]
"""
self.fig = Figure(figsize = figsize, dpi = dpi)
if tight_layout:
self.fig.set_constrained_layout(True)
self.plot_axes = []
i = 1
for _nx in range(nx):
for _ny in range(ny):
ax = self.fig.add_subplot(ny, nx, i, **kwargs)
self.plot_axes.append(ax)
i += 1
return self.fig, self.plot_axes
[ドキュメント]
def legend(self, ax, line_inf_list = None, draggable = True, **kwargs):
"""
指定されたAxesに凡例を追加します。
`line_inf_list` が指定された場合、その情報に基づいて凡例を作成します。
凡例はドラッグ可能に設定することができます。
このメソッドは、Matplotlibの `ax.legend()` 機能を拡張します。
:param ax: 凡例を追加するAxesオブジェクト。
:type ax: matplotlib.axes.Axes
:param line_inf_list: 凡例に表示するラインオブジェクトのリストのリスト。`sum()` で結合されます。
Noneの場合、`ax.legend()` のデフォルトの動作に従います(自動的に検出可能なハンドルを使用)。
:type line_inf_list: list[list[matplotlib.lines.Line2D]] or None
:param draggable: 凡例をマウスでドラッグ可能にするかどうか。Trueの場合、凡例を自由に移動できます。
:type draggable: bool
:param kwargs: `ax.legend()` に渡される追加のキーワード引数(例: loc, ncol, fontsize)。
:returns: 作成された凡例オブジェクト。
:rtype: matplotlib.legend.Legend
"""
if line_inf_list is not None:
ins = sum(line_inf_list)
labels = [l.get_label() for l in ins]
_legend = ax.legend(ins, labels, **kwargs)
else:
_legend = ax.legend(**kwargs)
_legend.set_draggable(draggable)
return _legend
# フィギュアをTkinterキャンバスに埋め込み
[ドキュメント]
def add_canvas(self, fig = None, parent = None):
"""
MatplotlibのFigureをTkinterキャンバスに埋め込み、表示します。
指定されたFigureをTkinterウィンドウに配置し、Matplotlibのナビゲーションツールバーも追加します。
これにより、パン、ズーム、保存などのMatplotlib標準機能が利用可能になります。
このメソッドは、プロットの表示をセットアップする上で中心的な役割を果たします。
:param fig: 埋め込むMatplotlibのFigureオブジェクト。Noneの場合、`self.fig` が使用されます。
:type fig: matplotlib.figure.Figure or None
:param parent: キャンバスを配置する親Tkinterウィジェット。Noneの場合、`self.parent` が使用されます。
:type parent: tkinter.Tk or tkinter.Widget or None
:returns: 作成されたFigureCanvasTkAggオブジェクト。
:rtype: matplotlib.backends.backend_tkagg.FigureCanvasTkAgg
"""
if parent is None:
parent = self.parent
if fig is None:
fig = self.fig
self.canvas = FigureCanvasTkAgg(fig, master = parent)
self.canvas.get_tk_widget().pack(side = tk.TOP, fill = tk.BOTH, expand = 1)
# Matplotlibのツールバーを作成
self.mpl_toolbar = NavigationToolbar2Tk(self.canvas, self.parent)
self.mpl_toolbar.update()
self.canvas.draw()
return self.canvas