2009年10月17日 星期六

如何使用 PyQwt 畫圖 (一)

設計資料分析用的 GUI 程式時,經常需要使用繪圖視窗來顯示數據資料畫成的圖。如果使用 PyQt 建立 GUI 程式的話,除了 Python 族群常用的 matplotlib 這個繪圖模組外,還可以使用 PyQwt 這個二維繪圖模組作為嵌入 GUI 的繪圖元件。PyQwt 畫出來的圖雖不若 matplotlib 美觀,可使用的繪圖功能也比 matplotlib 來得少,但是它可視作 PyQt 的延伸套件,能夠輕易地嵌入到用 PyQt 製作的 GUI 程式中,執行效率也比使用 matplotlib 來得高。如果 GUI 不需要顯示高品質圖形的話,那麼使用 PyQwt 作為繪圖元件將會是一個很好的選擇。可惜的是網路上有關 PyQwt 的學習資源很少,除了官方網站外,很難找到其它教學文獻,中文方面更是麟毛鳳角,因此我打算以四篇系列文章介紹如何使用 PyQwt 畫圖。文章中將假設讀者已經有 Python 與 PyQt 撰碼的經驗,因此只會針對 PyQwt 的相關部分作解釋。

在第一個範例中將介紹 PyQwt 最基本的繪製二維曲線功能,下圖為範例程式執行後輸出的圖形視窗:


本系列文章所有的範例都是在 Mircosoft Windows XP sp3 下執行,使用的 Python 版本與第三方模組版本如下:
  • Python 2.5.2
  • PyQt 4.4.3
  • PyQwt 5.1
  • Numpy 1.3
接下來我們來看程式碼:
#!/usr/bin/env python

import sys
import numpy as np
from PyQt4.QtCore import *
from PyQt4.QtGui import *
from PyQt4.Qwt5 import *


class Ex01(QWidget):

    def __init__(self):
        QWidget.__init__(self)
        fig = QwtPlot()
        fig.setParent(self)

        text = "f(x) = sin(x) + 0.1x<sup>2<\sup>"
        fig.setTitle(text)
        fig.setAxisTitle(fig.xBottom, "x")
        fig.setAxisTitle(fig.yLeft, "f(x)")

        x = np.arange(0, 10, 0.01)
        y = np.sin(x) + 0.1*x**2

        curve = QwtPlotCurve()
        curve.setData(x, y)
        curve.attach(fig)
        fig.replot()

        fig.resize(400, 300)

def main():
    app = QApplication(sys.argv)
    frame = Ex01()
    frame.show()
    app.exec_()


if __name__ == "__main__":
    main() 
一開始我們匯入必要的模組,其中 PyQt4.Qwt5 即為 PyQwt 模組。因為所有 Qt 與 Qwt 的命名空間、類別、與函式等屬性都帶有前綴字 Q 與 Qwt,所以我們使用「import *」的敘述,將模組內所有的東西都匯進來,而不用擔心命名衝突的問題。接下來我們建立一個繼承自 QWidget 的類別:Ex01,在此類別內分別建立兩個 Qwt 的類別物件 fig 與 curve。fig 是個型態為 QwtPlot 的物件,這個物件提供一個二維的畫布,讓我們可以在上面放上曲線、格線、marker 等各種 QwtPlotItem 物件來呈現我們想要表達的資訊。QwtPlot 物件方法的 .setTitle(String) 可以讓我們設定圖的標題文字;而 .setAxisTitle(AxisId, String) 則是用來設定座標軸的標題,fig.xBottm 與 fig.yLeft 為 QwtPlot 物件的常數成員,分別代表 fig 的下方 x 軸與左方 y 軸。預設上只出現這兩個軸,如果有需要我們可以使用 .enableAxis(AxisId, bool) 這個物件方法來開啟另外兩個 (.xTop 與 .yRight) 座標軸。

QwtPlotCurve 是 QwtPlotItem 的子類別,用來表現二維的曲線圖,曲線的預設值為黑色的實線,但其樣式(實線或虛線等)、線寬、與顏色等特徵都可以另外設定。利用其物件方法 .setData(x, y) 可以將 x, y 的值繪製成曲線,再用 .attach(fig) 將曲線貼附在 fig 的畫布上,最後以 fig.replot() 更新 fig 畫布的內容。因為 QwtPlot 物件可以視作 QWidget,因此嵌入在 PyQt 的程式中毫不費力,在範例中我們直接將 fig 的 parent 設為 Ex01,這樣就完成圖形物件的嵌入。

上面完成的圖還有很多改進的空間,下一篇文章我們將探討如何改進圖的外觀。

(發佈日期:2009/10/17)
(修改日期:2010/02/04)

沒有留言:

張貼留言