Matplotlibで必要なラインを選択して描写する

https://qiita.com/Nomisugi/items/b5f7e5d191212bef2a8a

前回に続いて、Matplotlibでリアルタイムグラフを描写させますが、目視必要ないラインを表示させたくない事もあり表示ラインを選択できるようにプログラムを修正してみました。

####Matplotlibラインの非表示
ラインに対して、set_visible を使い(True / False)で表示非表示を切り替えられるのがわかりました。

####動作イメージ
左側にlineを選択できるチェックボックスを作ってみました

![graph1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/506495/d6ce235a-32d5-675b-747f-ee6e6db93740.png)

チェックボックスを外すとそのライン消えます

![graph2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/506495/12018b85-2e63-931a-136e-b0fdff69f5d4.png)


####ソースコード
```python:SelectableGraph.py
import numpy as np
import tkinter as tk
import tkinter.ttk as ttk
import math

from matplotlib.backends.backend_tkagg import (
    FigureCanvasTkAgg, NavigationToolbar2Tk)
from matplotlib.figure import Figure
import matplotlib.animation as animation

class GraphFrame(ttk.Frame):
    def __init__(self, master, graph_num):
        super().__init__(master)
        #Graph view
        fig = Figure()
        canvas = FigureCanvasTkAgg(fig, master=master)
        self.x = np.arange(0, 10, 0.1)
        self.y_datas = []
        for y in range(graph_num):
            self.y_datas.append( np.zeros(100) )
        l = np.arange(0, 10, 0.01)
        plt = fig.add_subplot(111)
        plt.set_ylim([-2, 2])
        plt.set_position([0.07, 0.05, 0.9, 0.9])
        self.lines = []
        for y in range(graph_num):
            yp, = plt.plot(self.y_datas[y])
            self.lines.append( yp, )

        ani = animation.FuncAnimation(fig, self.animate, l,
                                      interval=20, blit=True,
        )
        canvas.get_tk_widget().pack()

    def animate(self, i):
        count = 0
        for line in self.lines:
            line.set_ydata(self.y_datas[count])
            count+=1
        return self.lines[0:]

    def setValues(self, vals):
        count = 0
        for val in vals:
            self.y_datas[count] = np.append(self.y_datas[count], val)
            self.y_datas[count] = np.delete(self.y_datas[count], 0)
            count+=1

    def visible(self, opts):
        count = 0
        for opt in opts:
            self.lines[count].set_visible(opt.get())
            count+=1

class SelectableGraph(ttk.Frame):
    def __init__(self, master, graph_list):
        super().__init__(master)
        self.pack()

        self.graph_num = len(graph_list)
        
        select_frame = ttk.LabelFrame(self, text= "line Select",relief = 'groove')
        select_frame.pack(side = 'left', anchor = tk.N)

        def on_check():
            self.gf.visible(opts)

        opts = [tk.BooleanVar() for _ in range(self.graph_num)]
        for item in opts:
            item.set(True)
        for i in range(self.graph_num):
            ttk.Checkbutton(select_frame, text = graph_list[i],
                            variable = opts[i], command=on_check).pack()        
        
        graph_frame = ttk.Frame(self)
        self.gf =GraphFrame(graph_frame, self.graph_num)
        graph_frame.pack(side = 'right', fill = 'x')

    def setValues(self, vals):
        self.gf.setValues(vals)
        

class RealtimeUpdateGraph(ttk.Frame):
    def __init__(self, master):
        super().__init__(master)
        self.test_count = 0
        self.master = master

        #Selectable lines
        graph_list = ["sin", "cos", "tan"]
        graph_frame = ttk.Frame(master)
        self.gf =SelectableGraph(graph_frame, graph_list)
        graph_frame.pack(side = 'right', fill = 'x')

        self.update()

    def update(self):
        vals = []
        vals.append( math.sin(math.radians(10*self.test_count)))
        vals.append( math.cos(math.radians(10*self.test_count)))
        vals.append( math.tan(math.radians(10*self.test_count)))                
        self.gf.setValues( vals )
        self.test_count+=1
        self.master.after(100, self.update)


if __name__ == "__main__":
    win = tk.Tk()
    gh = RealtimeUpdateGraph(win)
    win.mainloop()

```

こんなコード書かなくても、matplotlibに標準機能でグラフ表示をON/OFFできるかもしれません。
凡例ラベルにグラフ表示ON/OFFできる機能をご存じの方がいればアドバイス頂ければと思います。