Python PySideで作ったGUIにMatplotlibを埋め込んでみた（以前の記事のMatplotlib版）

#前回の記事
[前回は、](http://qiita.com/yozi/items/71f5b43ea99258d5fb81)PySideで作ったGUIに、pyqtgraphでプロットしてみました。

#今回の目的
前回のような書き方で、pyqtgraphではなく、matplotlibを動かしてみます。

#とりあえずこれをim2.pyとして保存し、実行する。

```python:im2.py
from PySide import QtCore, QtGui

import matplotlib.pyplot as plt

import matplotlib
matplotlib.rcParams['backend.qt4'] = 'PySide'

from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas

class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        self.centralwidget = QtGui.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        MainWindow.setCentralWidget(self.centralwidget)
        
        self.verticalLayout = QtGui.QVBoxLayout(self.centralwidget)
        self.verticalLayout.setObjectName("verticalLayout")
        
        self.fig = plt.Figure()
        self.graph01 = FigureCanvas(self.fig)
        self.ax1 = self.fig.add_subplot(211)
        self.ax2 = self.fig.add_subplot(212)
        
        self.graph01.setObjectName("graph01")
        self.verticalLayout.addWidget(self.graph01)
        
        self.psbtn = QtGui.QPushButton(self.centralwidget)
        self.psbtn.setObjectName("psbtn")
        self.psbtn.setText("Plot")
        self.verticalLayout.addWidget(self.psbtn)
        QtCore.QObject.connect(self.psbtn, QtCore.SIGNAL("clicked()"), self.plot)
        
    def plot(self):
        frq1 = 10.0
        frq2 = 30.0
        frq3 = 50.0
        duration = 1.0
        samples = 1001
        
        x1 = np.linspace(0, duration, samples)
        rad1 = np.linspace(0, 2 * np.pi * frq1, samples)
        rad2 = np.linspace(0, 2 * np.pi * frq2, samples)
        rad3 = np.linspace(0, 2 * np.pi * frq3, samples)
        y1 = np.sin(rad1) + np.sin(rad2) + np.sin(rad3) 
        
        x2 = np.linspace(0,1001,1001)[0:np.floor(len(y1)/2)]
        y2 = abs(np.fft.fft(y1))[0:np.floor(len(y1)/2)]
        
        self.ax1.plot(x1, y1)
        self.ax2.plot(x2, y2)
        self.graph01.draw()#zettai iru

import sys
import numpy as np

class ControlMainWindow(QtGui.QMainWindow):
    def __init__(self, parent=None):
        super(ControlMainWindow, self).__init__(parent)
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)

if __name__ == "__main__":
    app = QtGui.QApplication(sys.argv)
    mySW = ControlMainWindow()
    mySW.show()
    sys.exit(app.exec_())

```

#こうなる。
![20160831 screenshot 41.png](https://qiita-image-store.s3.amazonaws.com/0/137888/c7216aeb-e347-deef-8c98-c19031211d4c.png)
![20160831 screenshot 4.png](https://qiita-image-store.s3.amazonaws.com/0/137888/8d351e80-2f65-e84f-93b0-b4720639b21b.png)

# 注意
このままだと、plotボタンを押すたびに、プロットが上書きされて、たまっていく一方なので、プロットする前に、クリアするべきだった。
押すたびに色違いのグラフが描かれていく。
使用メモリがたまっていく様子は、Windowsのタスクマネージャーや、linuxなら「top」コマンド等から見れる。

#変更点は...
- import

import pyqtgraph as pg
↓
1 import matplotlib.pyplot as plt
2 import matplotlib
3 from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas

1個目は、定番。figure, subplot, plot, draw() などで使用した。
2個目は、PySideで使うためのおまじない。 rcParamsの['backend.qt4']を、'PySide'としないとだめらしい。
3個目は、PySideに入れるための部品のimport。plt.figure.Figureは、PySideに直接入れられない。このFigureCanvasQTAggの中にfigureを入れて、それを、addWidgetする。pyqtgraphでいうところの、plotWidget。


- PlotWidget ⇒ FigureCanvasQTAgg

self.graph = pg.PlotWidget(self.centralwidget)
↓
self.fig = plt.Figure()
self.graph = FigureCanvas(self.fig)
self.ax = self.fig.add_subplot(***)

- plot

self.graph.plot(x,y)
↓
self.ax.plot(x,y)
(場合によっては、↓も要る)
plt.draw()


全体的に、matplotlibでは行数が増えた。
##タイトルとは関係ないけど、前回から変更した点。
前回の10 Hzの信号から、複数の周波数の信号を足し合わせた信号に変えた。
その信号yを使って、abs(fft(y))して、サブプロットし下段に描いた。

#MatplotlibとPyQtGraphの比較
##メリット
- matplotlibのメリット
        - LaTeXが使える!
        - matplotlibの扱いに既に慣れていて、（subplotで作ったax1,ax2に次々プロットしては更新し...とか）分かっているのであれば便利。
    - 機能が豊富。(特に、[plt.xscale('symlog')など、pyqtgraphにはない機能が気に入っています。](http://naga-tsuzuki.sblo.jp/article/175204181.html)）
    - 枠の位置などの体裁が整っている。
    - 自動的に適切な大きさのグラフになる。
    - 公式サイトの[example](http://matplotlib.org/examples/index.html#)や、[gallery](http://matplotlib.org/gallery.html)を見れば、大抵解決。

- pyqtgraphのメリット
    - 多点プロット時に速い 
    - コードが、matplotlibよりも簡潔にできる。
    - **(重要)プログラムしなくても、既にインタラクティブなグラフになっている。**
        - グラフのズーム、シフトが、プログラムしなくてもできる。グラフを左クリックでドラッグ⇒上下左右に移動。右クリックでドラッグ⇒ズーム
        - 右クリックで、出てくるメニューがすごい。データ点をtxtで排出したり、画像として保存したりできる。
        log⇔linearの表示切り替えも、後からできる。
        （試してはいないが、）この機能をオフにもできると思う。
        ![20160831 screenshot 1.png](https://qiita-image-store.s3.amazonaws.com/0/137888/11e987ad-f042-f897-443e-d09d78b55d20.png)


##ディメリット
- matplotlibのディメリット
 - (PySideの場合)いろいろ付け足す必要ある。参考：[PythonでmatplotlibとPySideを連携させる](http://qiita.com/mountcedar/items/ccf671a497563b0cd671)
 - ax.plot(x,y)等を書く場所によっては、draw()しないと、グラフ描いてくれない。自分の場合、axを作った関数内なら、plotするだけでプロットしてくれるが、それ以外の関数内でax.plotなどをやっても、何も書いてくれない⇒次の行とかにdraw()があると書いてくれる。
 - デザインが変わる。
        - 自動的に、アプリの縦横サイズでかくなる。
        - グラフ領域の背景が、灰色になる。
 - 多点プロットで遅い。

- pyqtgraphのディメリット
    - **LaTeXが使えない！！！！！！！！！！！！！**
    - グラフの枠が見切れる。
    ![20160831 screenshot 2.png](https://qiita-image-store.s3.amazonaws.com/0/137888/5022b6b9-4f61-c009-a1c1-7c3a5eede3d0.png)
    ![20160831 screenshot 3.png](https://qiita-image-store.s3.amazonaws.com/0/137888/173d3895-7ef4-81a1-6eb6-e60015685a5a.png)


    - 自動で、グラフの大きさを調節してくれない。[前回のim.pyのように、](http://qiita.com/yozi/items/71f5b43ea99258d5fb81#%E3%81%93%E3%81%86%E3%81%AA%E3%82%8B)アプリの大きさを指定しないと、ものすごい小さいプロットを作ってくる。
    
    - ディフォルトの背景黒く、怪しい。直すには、2行くらい必要。
        - pg.setConfigOption('foreground', 'k')
        - pg.setConfigOption('background', 'w')

#pyqtgraphは
**（重要）ユーザーの少なさから、情報量が圧倒的にmatplotlibに負けているけど、pysideや、pyqt上での使い方は、案外あっさり分かる仕組みがある↓**

>import pyqtgraph.examples
>pyqtgraph.examples.run()

![20160831 screenshot 42.png](https://qiita-image-store.s3.amazonaws.com/0/137888/a959a138-3571-b667-6070-7d5115acb8b6.png)
圧倒的（それでもmatplotlibには負けるが）に充実したサンプルが、コード付きで見られる。
![20160831 screenshot 43.png](https://qiita-image-store.s3.amazonaws.com/0/137888/3faf4f93-d6c3-8a69-c512-2b8945e97a65.png)

ここに、ちゃんと載っているんだけれども、英語は自動的にシャットアウトしてしまうので見逃しがちだった。
http://www.pyqtgraph.org/documentation/introduction.html#examples

##訳

>例

>>PyQtGraphは、広範囲な使用例のセットが含まれています。 下記を実行すれば、その使用例にアクセスできます。

>>>import pyqtgraph.examples
>>>pyqtgraph.examples.run()

>>これで、使用可能な例のリストを持つランチャーが、開始されます。項目を選んで、そのソースコードを見たり、項目をダブルクリックして、使用例を実行したりして下さい。


##要するに
私は、pyqtgraph推し。

#個人的な感想
　この記事だけ見ると、matplotlibは、行数多く必要だったり、遅かったりと、ディメリットだらけの様だが、subplotなど、細かい設定をすればするほど、matplotlibの方が、使い勝手が良くなっていくのではないかと思う。

「たかだか、作図のために、何種類もAPIの使い方覚えるとか馬鹿らしい」というのも正論。
ただ、pythonだけでも、何種類も作図のライブラリはあって、それぞれ一長一短があるのも事実。

- 論文や報告書に載せるようなグラフを、きれいに仕上げたい場合は、matplotlib
- GUIに入れるなら、pyqtgraph

とか使い分けてもいい気がする。

個人のブログには、誰もコメントを書いてくれないので、コメントを頂いてすごい嬉しかったので、再度投稿してみました。~~QiitaのSEOは素晴らしいですね。~~