#前回の記事
前回は、PySideで作ったGUIに、pyqtgraphでプロットしてみました。
#今回の目的
前回のような書き方で、pyqtgraphではなく、matplotlibを動かしてみます。
#とりあえずこれを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_())
注意
このままだと、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にはない機能が気に入っています。)
- 枠の位置などの体裁が整っている。
- 自動的に適切な大きさのグラフになる。
- 公式サイトのexampleや、galleryを見れば、大抵解決。
-
pyqtgraphのメリット
##ディメリット
-
matplotlibのディメリット
-
(PySideの場合)いろいろ付け足す必要ある。参考:PythonでmatplotlibとPySideを連携させる
-
ax.plot(x,y)等を書く場所によっては、draw()しないと、グラフ描いてくれない。自分の場合、axを作った関数内なら、plotするだけでプロットしてくれるが、それ以外の関数内でax.plotなどをやっても、何も書いてくれない⇒次の行とかにdraw()があると書いてくれる。
-
デザインが変わる。
- 自動的に、アプリの縦横サイズでかくなる。
- グラフ領域の背景が、灰色になる。 -
多点プロットで遅い。
-
pyqtgraphのディメリット
-
LaTeXが使えない!!!!!!!!!!!!!
-
自動で、グラフの大きさを調節してくれない。前回のim.pyのように、アプリの大きさを指定しないと、ものすごい小さいプロットを作ってくる。
-
ディフォルトの背景黒く、怪しい。直すには、2行くらい必要。
- pg.setConfigOption('foreground', 'k')
- pg.setConfigOption('background', 'w')
-
#pyqtgraphは
(重要)ユーザーの少なさから、情報量が圧倒的にmatplotlibに負けているけど、pysideや、pyqt上での使い方は、案外あっさり分かる仕組みがある↓
import pyqtgraph.examples
pyqtgraph.examples.run()
圧倒的(それでもmatplotlibには負けるが)に充実したサンプルが、コード付きで見られる。
ここに、ちゃんと載っているんだけれども、英語は自動的にシャットアウトしてしまうので見逃しがちだった。
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は素晴らしいですね。