「解決したいこと」:TkinterでGUIを作成し、その中でmatplotlibのFuncAnimationを使って、アニメーション描画をしています。
FuncAnimationの第三引数にnp.arange(1, 500)を入れた場合、アニメーションをすることを確認したため、この代わりに、Tkinterで、ボタンを押したら停止する処理を追加したいと考えました。
そのため、np.arangeの代わりに自前のメソッド(self.increment())を作って、ボタンを押したときに変更される「self.stop_mpl」の値がfalseのときは、更新しないように処理を記載しました。
しかしながら、一瞬アニメーションが停止する(ようにみえる?)のですが、
なぜかすぐにアニメーション(テストで書いているサイン波)が再開します。
いろいろ、調べたのですが、解決策が分かりませんでした。
もしよろしければ、解決策についてご教示いただければと思います。
以下に、matplotlibのfigureから、axesを取得し、アニメーションしているクラスを記載します。
python
1 2class MplCanvas: 3 def __init__(self, master=None, st_x=5.0, st_y=1.0, string="MPL_visualize_No.X"): 4 """ 5 :param master: 親widgetの実体(root, or flame) 6 :param st_x: mplのfigsize_x(単位pix, dpi=100) 7 :param st_y: mplのfigsize_y(単位pix, dpi=100) 8 :param string: mplの表示タイトル名 9 """ 10 # 描画関連(pane,fig,mpl,canvas,ax) 11 self.pane = tk.Frame(master, padx=15, pady=10) 12 self.fig = plt.Figure(figsize=(st_x, st_y)) 13 self.ax = self.fig.add_subplot(111) 14 self.fig.subplots_adjust(bottom=0.4) 15 self.mpl = tk.Label(self.pane, width=10, text=string) 16 self.mpl.grid(column=0, row=0) 17 18 # canvas割り当て 19 self.canvas = FigureCanvasTkAgg(self.fig, master=self.pane) 20 self.canvas.get_tk_widget() 21 self.canvas.get_tk_widget().grid(column=1, row=0) 22 23 self.x = np.arange(0, 2 * np.pi, 0.01) # x軸 24 self.s_df = pd.DataFrame(index=[], columns=[]) 25 self.stop_mpl = True 26 self.line, self.line2, self.line3 = None, None, None 27 self.t = 0 # mpl表示用データのインデックス(経過時間t) 28 self.t_max = 5000 # mpl表示用データのインデックス(最大) 29 30 xax = self.ax.xaxis 31 yax = self.ax.yaxis 32 self.ax.set_xlabel("x軸") 33 self.ax.set_ylabel("y軸") 34 print('xax.get_major_formatter()', xax.get_major_formatter()) 35 print('yax.get_major_formatter()', yax.get_major_formatter()) 36 print('xax.get_major_locator():', xax.get_major_locator()) 37 print('yax.get_major_locator():', yax.get_major_locator()) 38 39 # canvasに書くものを決定。(プロット初期化) 40 def setting_plot(self, disp_df=None): 41 # ためしにサイン波を書いてみる。 42 self.line, = self.ax.plot(self.x, np.sin(self.x)) 43 self.line2, = self.ax.plot(self.x, np.sin(self.x)) 44 45 def pack(self): 46 self.pane.pack() 47 48 def place(self, x, y): 49 self.pane.place(x=x, y=y) 50 51 # animation自体の更新関数。トリガはstart_animate()で実施。 52 def animate2(self, i): 53 self.line.set_data(self.x, np.sin(self.x + i / 10.0)) 54 self.line2.set_data(self.x, np.sin(self.x + i / 5.0)) 55 self.ax.grid(b=True, color='k', linestyle='--', linewidth=0.5) 56 return self.line, self.line2, 57 58 # pandas_dfを使う形の場合 59 def animate3(self, i): 60 self.line = self.ax.plot(self.s_df.iloc[:, 2], self.s_df.iloc[:, 3]) 61 self.line2 = self.ax.plot(self.s_df.iloc[:, 2], self.s_df.iloc[:, 4]) 62 self.line3 = self.ax.plot(self.s_df.iloc[:, 2], self.s_df.iloc[:, 5]) 63 # self.line.set_ydata(np.sin(self.x + i / 10.0)) # update the data 64 return self.line, self.line2, self.line3, 65 66# x(t?)を進める関数(グラフのx軸値(時間t?)を進める) 67 def increment(self): 68 if not self.stop_mpl: # mplが停止中じゃないとき 69 if self.t < self.t_max: # 範囲内のとき 70 self.t += 1 71 yield self.t 72 73# アニメーション開始 74 def start_animate(self, flg_stop=False): 75 self.stop_mpl = flg_stop 76# self.ani2 = animation.FuncAnimation(self.fig, self.animate2, np.arange(1, 500), interval=50, blit=False, 77# repeat=True) 78 self.ani2 = animation.FuncAnimation(self.fig, self.animate2, self.increment, interval=50, blit=False, 79 repeat=True)

回答1件
あなたの回答
tips
プレビュー