tkinterのGUIを使ってmatplotlibのfigやaxesの配置をシュミレーションできるプログラムを組んでみた①

matplotlib

はじめに

こんにちは、でめきんです。

matplotlibで1枚の画像を表示する時、その設定は特に困る事はないのですが複数枚のグラフや画像を表示する時にその設定をすることがとても苦手なんです。

そこで、今回figの大きさや、axesの配置設定をシュミレーションできるプログラムを組んでみました。入力フォームにtkinterのGUIを用いました。ただ、かなりやっつけ的な感じで組んだので出来はあまりよくありませんが興味のある方は一度お試しあれです。


条件を考える

まずは、条件を考えていきましょう。今回私が考えた条件は以下の4点です。

  • figの大きさを変えられるようにしたい
  • axesの数は変えられるようにしたい。
  • fig上での余白を設定できるようにしたい
  • 画像間隔を設定できるようにしたい

これらの条件を変更できるようにするにはpythonの標準ライブラリーのtkinterを用いてGUIを作成することにしました。

entrytウィジェット(数値を入力できる枠)は

  • figの大きさ、axesの数の設定に2個づつで4個
  • figの余白設定で上下左右なので4個
  • 画像の間隔を指定するのに2個

全てで合計10個のentryウイジェットが必要になります。

その他に、実行ボタン。

それぞれのラベルfigsize,axesの数,余白設定,画像間隔のラベルを作成したいので

ラベル4つが必要になります。

※ウイジェットとは、パーツを指します。ラベルであったり、文字入力の欄であったり、ボタンであったりです。


tkinter、まずはウイジェットを配置するウインドウ作成

それでは、ウイジェットを配置するためのウインドウを作成しその後にメインフレームを作成しましょう。

初めてtkinterを使った時、この設定が全く分かりませんでした。はじめにメインウインドウを作成して、その後にフレームを作成してと・・・・同じような事を2回も繰り返して・・・・なぜ?

以前も記載しましたが、今回も同じ。考え方としては何が絵を描こうとするときに机、もしくは画板等の台を用意すると思います。それがメインウインドウ。ただ、その机や画板に直接絵を描くわけではなく、台の上に紙や、画用紙を置いて書くと思います。その紙に当たるのがメインフレームに当たります。

コードを書いていきます。まずは、tkinterをインポートするところから始めます。


# -- coding utf-8 --

import tkinter
from tkinter import ttk

そして、机に当たるメインウインドウを作ります。


# -- coding utf-8 --

import tkinter
from tkinter import ttk

# メインウィンドウ
main_win = tkinter.Tk()
main_win.title("matplotlib 領域")
main_win.geometry("230x210")

8行目ではウインドウ名(GUIの上に表示できる名前)の設定と、9行目でサイズの指定を行っています。

その後にフレームの作成になります。


# -- coding utf-8 --

import tkinter
from tkinter import ttk

main_win = tkinter.Tk()
main_win.title("matplotlib 領域")
main_win.geometry("230x210")

# メインウィンドウ
main_win = tkinter.Tk()
main_win.title("matplotlib 領域")
main_win.geometry("230x210")

# メインフレーム
main_frm = ttk.Frame(main_win)

17行目でメインフレームをメインウインドウの中に割り当てています。


tkinter、グリッドの設定とウイジェットの作成

tkinterの配置はgrid関数を使って当てはめていきます。

感じとしてはExcelを想像してもらうといいかもしれません。

グリッド設定

まずはメインフレームにグリッドを指定し、フレーム内のどこに設定するか決めます。


# -- coding utf-8 --

import tkinter
from tkinter import ttk

main_win = tkinter.Tk()
main_win.title("matplotlib 領域")
main_win.geometry("230x210")

# メインウィンドウ
main_win = tkinter.Tk()
main_win.title("matplotlib 領域")
main_win.geometry("230x210")

# メインフレーム
main_frm = ttk.Frame(main_win)
main_frm.grid(column=0, row=0, sticky=tkinter.NSEW)

18行目でNSEWとありますが、これは北南東西の意味になっています。

これで、メインフレームのグリッドの設定は終わりました。


ウイジェットの作成

ウイジェットはいろいろありますが、今回はLabel、Entry、Buttonを使います。

Labelの設定は

変数名 = ttk.Label(“配置するフレーム名”,”フレームに入れる文字列”,width = ラベルの幅,Justify = 配置設定)

で指定します。今回は

  • figsize
  • axの数
  • 余白設定
  • 画像間隔

の4つを作成します。それぞれ幅は10に設定します。


# -- coding utf-8 --

import tkinter
from tkinter import ttk

main_win = tkinter.Tk()
main_win.title("matplotlib 領域")
main_win.geometry("230x210")

# メインウィンドウ
main_win = tkinter.Tk()
main_win.title("matplotlib 領域")
main_win.geometry("230x210")

# メインフレーム
main_frm = ttk.Frame(main_win)
main_frm.grid(column=0, row=0, sticky=tkinter.NSEW)

#ラベルの作成
fig_label = ttk.Label(main_frm, text="figsize",width =10)
ax_label = ttk.Label(main_frm, text="axの数",width =10)
ax_area_row = ttk.Label(main_frm, text="余白設定",width =10)
ax_space = ttk.Label(main_frm, text="画像間隔",width =10)

justifyの設定はデフォルトが左寄せなので今回は省略しました。


続いてEntryの設定です。

変数名 = ttk.Entry(“配置するフレーム名”,width =Entryの幅,justify=配置設定)

で設定していきます。

今回作成するEntryは配置するフレーム、大きさや、配置設定は全て同じになりますので項目ごとに1行で書いていく事にします。

書き方の例としては変数aとbに1と9の数字を代入する場合を考えてみたいと思います。

a , b = 1 , 9

の様にすることでそれぞれに代入できます。

figの設定では、縦と横があります。変数名をそれぞれfig_row,fig_colとします。

fig_row , fig_col = ttk.Entry(main_frm) , ttk.Entry(main_frm)

で設定することが出来ます。簡素化のためにwithとjustifyの設定は省略しました。同様にaxの設定と余白、画像間隔のEntryを作成していきます。


# -- coding utf-8 --

import tkinter
from tkinter import ttk

main_win = tkinter.Tk()
main_win.title("matplotlib 領域")
main_win.geometry("230x210")

# メインウィンドウ
main_win = tkinter.Tk()
main_win.title("matplotlib 領域")
main_win.geometry("230x210")

# メインフレーム
main_frm = ttk.Frame(main_win)
main_frm.grid(column=0, row=0, sticky=tkinter.NSEW)

#ラベルの作成
fig_label = ttk.Label(main_frm, text="figsize",width =10)
ax_label = ttk.Label(main_frm, text="axの数",width =10)
ax_area_row = ttk.Label(main_frm, text="余白設定",width =10)
ax_space = ttk.Label(main_frm, text="画像間隔",width =10)

#Entryの作成
fig_row,fig_col = ttk.Entry(main_frm,width =5,justify="center"),ttk.Entry(main_frm,width =5,justify="center")
ax_box_row,ax_box_col = ttk.Entry(main_frm,width =5,justify="center"),ttk.Entry(main_frm,width =5,justify="center")
ax_area_l,ax_area_r = ttk.Entry(main_frm,width =5,justify="center"),ttk.Entry(main_frm,width =5,justify="center")
ax_area_u,ax_area_d = ttk.Entry(main_frm,width =5,justify="center"),ttk.Entry(main_frm,width =5,justify="center")
ax_space_hspace,ax_space_wspace = ttk.Entry(main_frm,width =5,justify="center"), ttk.Entry(main_frm,width =5,justify="center")

後は実行ボタンの作成です。

ボタンの設定は以下となります

変数名 = ttk.Button(“配置するフレーム名”, text=”文字列”,command = 実行する関数)

となります。今回、実行する関数は”matplot_show”とします。(後で作成します。)


# -- coding utf-8 --

import tkinter
from tkinter import ttk

main_win = tkinter.Tk()
main_win.title("matplotlib 領域")
main_win.geometry("230x210")

# メインウィンドウ
main_win = tkinter.Tk()
main_win.title("matplotlib 領域")
main_win.geometry("230x210")

# メインフレーム
main_frm = ttk.Frame(main_win)
main_frm.grid(column=0, row=0, sticky=tkinter.NSEW)

#ラベルの作成
fig_label = ttk.Label(main_frm, text="figsize",width =10)
ax_label = ttk.Label(main_frm, text="axの数",width =10)
ax_area_row = ttk.Label(main_frm, text="余白設定",width =10)
ax_space = ttk.Label(main_frm, text="画像間隔",width =10)

#Entryの作成
fig_row,fig_col = ttk.Entry(main_frm,width =5,justify="center"),ttk.Entry(main_frm,width =5,justify="center")
ax_box_row,ax_box_col = ttk.Entry(main_frm,width =5,justify="center"),ttk.Entry(main_frm,width =5,justify="center")
ax_area_l,ax_area_r = ttk.Entry(main_frm,width =5,justify="center"),ttk.Entry(main_frm,width =5,justify="center")
ax_area_u,ax_area_d = ttk.Entry(main_frm,width =5,justify="center"),ttk.Entry(main_frm,width =5,justify="center")
ax_space_hspace,ax_space_wspace = ttk.Entry(main_frm,width =5,justify="center"), ttk.Entry(main_frm,width =5,justify="center")

#ボタンの作成
app_btn = ttk.Button(main_frm, text="実行",command = matplot_show)


tkinter、GUIの配置シュミレーション

続いて、作成してきたウイジェットをグリッド内に配置していく作業です。

いきなり作業に入る前にexcelを用いて簡単にシュミレーションするのがお勧めです。今回の配置は以下の様にしてみました。

上記図において緑色が0列目、黄色が1列目、水色が2列目、橙色が3列目となります。また、0行目、1行目、6行目はグリッドの結合を行います。

設定は以下となります。

fig_label.grid(row=1, column=0)
fig_row.grid(row=1, column=1)
fig_col.grid(row=1, column=2,columnspan=2)

ax_label.grid(row=2, column=0)
ax_box_row.grid(row=2, column=1)
ax_box_col.grid(row=2, column=2,columnspan=2)

ax_area_u.grid(row=3,column=2)

ax_area_l.grid(row=4,column=1)
ax_area_r.grid(row=4,column=3)

ax_area_d.grid(row=5,column=2)

ax_space.grid(row=6,column=0)
ax_space_hspace.grid(row=6,column=1)
ax_space_wspace.grid(row=6,column=2,columnspan=2)

app_btn.grid(row=7, column=0,columnspan=4)

main_win.mainloop()


Entryウイジェットの初期値を与える

Entryウイジェットで入力できるようにしましたが、全ての項目を入力するのは非常に手間です。なので、初期値を設定しましょう。

初期値の設定は

変数名.insert(初めの文字の場所 , “初期値”)

で設定します。

なので、初期値として

Figsizeを縦5、横4、axesを縦2、横2、余白設定を左と下を0、右と上を1、画像間隔を縦横それぞれ0.1として設定します。

fig_row.insert(0,"4"),fig_col.insert(0,"5")
ax_box_row.insert(0,"2"),ax_box_col.insert(0,"2")
ax_area_l.insert(0,"0"),ax_area_r.insert(0,"1")
ax_area_u.insert(0,"1"),ax_area_d.insert(0,"0")
ax_space_hspace.insert(0,"0.1"),ax_space_wspace.insert(0,"0.1")

を上のコードの下に追加します。

初期値の設定が終わったら、GUIを表示し続けるコード

main_win.mainloop()

を足してください。これがないとGUIが表示されません。


確認

とりあえず、ここまででGUIの部分は完成しましたので実行ボタンの関数を仮で作りプログラムを走らせてみましょう。

モジュールインポートの後、6行目辺りに以下のコードを挿入してください。


def matplot_show():
    pass

完成コードは以下になります。

# -- coding utf-8 --

import tkinter
from tkinter import ttk

def matplot_show():
    pass


# メインウィンドウ
main_win = tkinter.Tk()
main_win.title("matplotlib 領域")
main_win.geometry("230x210")

# メインフレーム
main_frm = ttk.Frame(main_win)
main_frm.grid(column=0, row=0, sticky=tkinter.NSEW)

#ラベルの作成
fig_label = ttk.Label(main_frm, text="figsize",width =10)
ax_label = ttk.Label(main_frm, text="axの数",width =10)
ax_area_row = ttk.Label(main_frm, text="余白設定",width =10)
ax_space = ttk.Label(main_frm, text="画像間隔",width =10)

#Entryの作成
fig_row,fig_col = ttk.Entry(main_frm,width =5,justify="center"),ttk.Entry(main_frm,width =5,justify="center")
ax_box_row,ax_box_col = ttk.Entry(main_frm,width =5,justify="center"),ttk.Entry(main_frm,width =5,justify="center")
ax_area_l,ax_area_r = ttk.Entry(main_frm,width =5,justify="center"),ttk.Entry(main_frm,width =5,justify="center")
ax_area_u,ax_area_d = ttk.Entry(main_frm,width =5,justify="center"),ttk.Entry(main_frm,width =5,justify="center")
ax_space_hspace,ax_space_wspace = ttk.Entry(main_frm,width =5,justify="center"), ttk.Entry(main_frm,width =5,justify="center")

#ボタンの作成
app_btn = ttk.Button(main_frm, text="実行",command = matplot_show)

fig_label.grid(row=1, column=0)
fig_row.grid(row=1, column=1)
fig_col.grid(row=1, column=2,columnspan=2)

ax_label.grid(row=2, column=0)
ax_box_row.grid(row=2, column=1)
ax_box_col.grid(row=2, column=2,columnspan=2)

ax_area_u.grid(row=3,column=2)

ax_area_row.grid(row=4,column=0)
ax_area_l.grid(row=4,column=1)
ax_area_r.grid(row=4,column=3)

ax_area_d.grid(row=5,column=2)

ax_space.grid(row=6,column=0)
ax_space_hspace.grid(row=6,column=1)
ax_space_wspace.grid(row=6,column=2,columnspan=2)

app_btn.grid(row=7, column=0,columnspan=4)

fig_row.insert(0,"4"),fig_col.insert(0,"5")
ax_box_row.insert(0,"2"),ax_box_col.insert(0,"2")
ax_area_l.insert(0,"0"),ax_area_r.insert(0,"1")
ax_area_u.insert(0,"1"),ax_area_d.insert(0,"0")
ax_space_hspace.insert(0,"0.1"),ax_space_wspace.insert(0,"0.1")

main_win.mainloop()

上記の様なGUIが表示されましたか?

ちょっと長くなってしまったので次回matplot_showの関数部分を作成してみたいと思います。

お疲れ様でした。

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