matplotlib.widgetsでスライダーを使う

matplotlib.widgetsでスライダーを使い、インタラクティブに描画を更新するプログラムを作った。

やりたいこと

マウスとキーボードによるユーザー入力に応じてグラフを更新する。以下の仕様で動くようにしたい。
・-5~5までのゲージメーター(スライダーと呼ばれている)内でクリックした位置にプロット線を移動させる
・キーボードで右と左の矢印を押したらプロット線の位置が横方向にそれぞれ+1、-1移動する。
・キーボードでAltと左右を同時押しした場合は、移動方向は上と同じで+2、-2移動する。

完成したもの

youtu.be

ソースコード

 import matplotlib.pyplot as plt
 from matplotlib.widgets import Slider
 import math

 xrange=5 ## -xrangeから+xrangeの範囲でプロット                                                                                                                                                                                                                                                 
 linepos = 0
 fig, ax = plt.subplots()
 xarray=[linepos for i in range(3)]
 yarray=[ i for i in range(3)]
 ax = plt.axis([-7,7,-4,4])
 l, = plt.plot(xarray,yarray, lw=1, marker="o")
 axamp = plt.axes([0.25, .03, 0.50, 0.02])
 # Slider                                                                                                                                                                                                                                                                                      
 slider = Slider(axamp, 'linepos', -xrange, xrange, valinit=0, valfmt='%d')

 def update(val):
     global linepos
     linepos = math.floor(slider.val)
     xarray=[linepos for i in range(3)]
     yarray=[ i for i in range(3)]
     l.set_xdata(xarray)
     l.set_ydata(yarray)
     fig.canvas.draw_idle()

 def onkey(event):
     global slider
     if event.key == 'right':
         if slider.val < xrange:
             slider.set_val(slider.val+1)
             print(slider.val)
     elif event.key == 'left':
         if slider.val > -xrange:
             slider.set_val(slider.val-1)
             print(slider.val)
     elif event.key == 'alt+right':
         if slider.val < xrange-1:
             slider.set_val(slider.val+2)
             print(slider.val)
         elif slider.val < xrange:
             slider.set_val(slider.val+1)
     elif event.key == 'alt+left':
         if slider.val > -xrange+1:
             slider.set_val(slider.val-2)
         elif slider.val > -xrange:
             slider.set_val(slider.val-1)

 cid = fig.canvas.mpl_connect('key_press_event', onkey)
 slider.on_changed(update)
 plt.show()

参考にしたもの

matplotlib.widgetsによるインタラクティブコントロール riptutorial.com matplotlib.widgetsドキュメント matplotlib.org