見出し画像

Python:matplotlib でスライダとボタン

Python入門に入れるべきか否か。マニュアルには追加したが。

 以前,matplotlib でスライダやボタンを作る方法を調べたが,さっぱりわからなかった。matplotlib  のページにあるんだけど,書いてあることの意味がわからなかったのだ。仕様書なので,書いてあるのは「作り方」ではない。
 しかし,Tkinter でやったために読めるようになった。

 まず,ネットで検索して,matplotlib でスライダを作っているというページをさがした。見つかったが,コードが載っているだけで説明はないので,以前ならわからなかっただろう。そのページも,matplotlib のページに載っている例をコピーしたようなものだ。
 それでも,そのコードを元に,いろいろ試して,やりかたがわかった。

 高校の「情報Ⅰ」でスライダやボタンの作り方を扱うかというと,否である。ただし,教材作りには必要だということを,2020年の情報関係基礎の例で示した。
 では,なぜ改めて,こんどはmatplotlib  で作るのか。数学で使いたいからだ。2次関数のグラフを,係数の値をスライダで変えながら動かす,とか,sin,cos,tan のグラフを切り替えるとか,用途はたくさんある。教員が,普通教室で教材提示として使うためだ。もちろん生徒に使わせてもいい。
 そういう用途には,GeoGebla や GRAPES がある,と思われるだろう。もちろん,その方が簡単なこともあるが,プログラムできると何かと重宝だ。

スライダ

スライダを作って値を取得する手順は次の通り。
 (1) スライダのための余白を設定
 plt.subplots_adjust(left, bottom, right, top, wspace, hspace)
 を使って余白を設定する。それぞれキーワード引数。
(2) スライダを作る
 Slider() で値の範囲などを設定し,戻り値を適当な変数に入れる。
 引数は,位置:ax, ラベル:label, 値の最小値:valmin, 値の最大値:valmax,
  初期値:valinit=0.5, ステップ値: valstep, 向き:orientation が主なところ。
 ax は plt.axes([x, y, width, height] ) の戻り値で指定。
 orientation は ’horizontal’ または ’vertical’ で,デフォルトは水平。
(3) スライダで取得した値を使う関数を作る
 スライダで取得した値を引数で受け取る。引数を val とすると,スライダ名.val  で参照できる。 スライダ名は,(2) で戻り値を受け取った変数名
(4) on_change メソッドで (3) の関数を呼び出す設定をする。
(3) の関数を update(val) とすると,スライダ名.on_change(update) と記述。


【例】2 次関数のグラフを,スライダで係数を変化させて描画する。 1 行目は,Jupyter Notebook を使うときに必要

%matplotlib notebook
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.widgets as wg
#from matplotlib.widgets import Slider
plt.figure(figsize=(6,6))
# 余白設定
plt.subplots_adjust(left=0.25, bottom=0.25)
plt.axis([-5,5,-3,7])
plt.grid()
plt.axhline(0, lw=1.5, color='k')
plt.axvline(0, lw=1.5, color='k')
plt.xticks(range(-5, 6))
plt.yticks(range(-3, 8))
x = np.linspace(-10, 10, 100)
a = 1
p = 0
q = 0
y = a * (x - p)**2 + q
l, = plt.plot(x, y, lw=2)
plt.text(0.5, 4.5, '$y=a(x-p)^2+q$', fontsize = 14) 
ax_a = plt.axes([0.25, 0.15, 0.6, 0.04])
ax_p = plt.axes([0.25, 0.10, 0.6, 0.04])
ax_q = plt.axes([0.25, 0.05, 0.6, 0.04])
sli_a = wg.Slider(ax_a, 'a', -5, 5, valinit=a,valstep=0.1)
sli_p = wg.Slider(ax_p, 'p', -5, 5, valinit=p,valstep=0.1)
sli_q = wg.Slider(ax_q, 'q', -5, 5, valinit=q,valstep=0.1)
def update(val):
   sa = sli_a.val
   sp = sli_p.val
   sq = sli_q.val
   l.set_ydata(sa * (x - sp)**2 + sq)
sli_a.on_changed(update)
sli_p.on_changed(update)
sli_q.on_changed(update)
plt.show()

画像1

ボタン

ボタンを作って表示を切り替えたりする手順は次の通り。
 (1) ボタンのための余白を設定
 スライダと同様。
(2) ボタンを作る
 Button() で値の範囲などを設定し,戻り値を適当な変数に入れる。 引数は,
 位置:ax, ラベル:label, 表示色:color, マウスオーバー時の色: hovercolor
 マウスオーバーとは,マウスがボタンの上に来たときのこと。
 ax はスライダと同様, plt.axes([x, y, width, height] ) の戻り値で指定。
(3) ボタンで呼び出す関数を作る ボタンをクリックしたときに動作する関数を
 作る。引数はない。
(4) on_clicked メソッドで (3) の関数を呼び出す設定をする。
(3) の関数を func() とすると,スライダ名.on_clicked(func) と記述。

【例】3 つの三角関数のグラフを,ボタンで切り替える。

%matplotlib notebook
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.widgets as wg
plt.figure(figsize=(6,4))
plt.axis([-4,8,-2,2])
plt.axhline(0, lw=1.5, color='k')
plt.axvline(0, lw=1.5, color='k')
plt.subplots_adjust(left=0.1, bottom=0.3,top=0.9)
x = np.arange(-4, 8, 0.01)
y = np.sin(x)
l, = plt.plot(x, y, lw=2, color='blue')
plt.title('trigonometrical function')
axcolor = 'lightgoldenrodyellow'
ax1 = plt.axes([0.2, 0.1, 0.15, 0.05])
ax2 = plt.axes([0.4, 0.1, 0.15, 0.05])
ax3 = plt.axes([0.6, 0.1, 0.15, 0.05])
btn1 = wg.Button(ax1, '$y=sin x$', color=axcolor, hovercolor='0.98')
btn2 = wg.Button(ax2, '$y=cos x$', color=axcolor, hovercolor='#CCFFCC')
btn3 = wg.Button(ax3, '$y=tan x$', color=axcolor, hovercolor='#FFCCCC')
def tosin():
   l.set_ydata(np.sin(x))
   l.set_color('blue')
def tocos():
   l.set_ydata(np.cos(x))
   l.set_color('green')
def totan():
   l.set_ydata(np.tan(x))
   l.set_color('red')
   
btn1.on_clicked(tosin)
btn2.on_clicked(tocos)
btn3.on_clicked(totan)
plt.show()

画像2