matplotlib嵌入到pyqt中

weixin_33763244發表於2018-09-09

在pyqt5中使用matplotlib

前言

雖然,qt中也提供了繪圖函式,但對於初學者並不是很容易掌握,眾所周知,matplot提供了簡單,易用,強大的繪圖函式,結合mumpy基本可以達到matlb中的繪圖體驗,並且比matlab更加具有擴充套件性,也更自由。通過matplotlib提供的官方例程的修改,就可以很容易的繪製你想要的圖形,真的很強大。(我也是名初學者)

matplotlib,pyqt5官方例程

# 取自matplotlib 官方文件案例

from __future__ import unicode_literals
import sys
import os
import random
import matplotlib
# Make sure that we are using QT5
matplotlib.use('Qt5Agg')

from PyQt5 import QtCore, QtWidgets
from numpy import arange, sin, pi, linspace
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.figure import Figure

progname = os.path.basename(sys.argv[0])
progversion = "0.1"


class MyMplCanvas(FigureCanvas):
    # 這既是一個wiget類也是一個FigureCanva

    def __init__(self, parent=None, width=5, height=4, dpi=100):
        self.fig = Figure(figsize=(width, height), dpi=dpi)
        self.axes = self.fig.add_subplot(111)

        self.compute_initial_figure()

        FigureCanvas.__init__(self, self.fig)
        self.setParent(parent)

        FigureCanvas.setSizePolicy(self,
                                   QtWidgets.QSizePolicy.Expanding,
                                   QtWidgets.QSizePolicy.Expanding)
        FigureCanvas.updateGeometry(self)

    def compute_initial_figure(self):
        pass


class MyStaticMplCanvas(MyMplCanvas):
    """Simple canvas with a sine plot."""

    def __init__(self, *args, **kwargs):
        MyMplCanvas.__init__(self, *args, **kwargs)
        

    def compute_initial_figure(self):
        print("hello world")
        x = linspace(0, 2 * pi, 500000)
        y = sin(x)
        self.axes.cla()
        self.axes.plot(x, y)
        self.draw()


class MyDynamicMplCanvas(MyMplCanvas):
    """A canvas that updates itself every second with a new plot."""

    def __init__(self, *args, **kwargs):
        MyMplCanvas.__init__(self, *args, **kwargs)
        timer = QtCore.QTimer(self)
        
        timer.timeout.connect(self.update_figure)
        timer.start(1000)

    def compute_initial_figure(self):
        self.axes.plot([0, 1, 2, 3], [1, 2, 0, 4], 'r')

    def update_figure(self):
        # Build a list of 4 random integers between 0 and 10 (both inclusive)
        l = [random.randint(0, 10) for i in range(4)]
        self.axes.cla()
        self.axes.plot([0, 1, 2, 3], l, 'r')
        self.draw()


class ApplicationWindow(QtWidgets.QMainWindow):
    def __init__(self):
        QtWidgets.QMainWindow.__init__(self)
        self.setAttribute(QtCore.Qt.WA_DeleteOnClose)
        self.setWindowTitle("application main window")

        self.file_menu = QtWidgets.QMenu('&File', self)
        self.file_menu.addAction('&Quit', self.fileQuit,
                                 QtCore.Qt.CTRL + QtCore.Qt.Key_Q)
        self.menuBar().addMenu(self.file_menu)

        self.help_menu = QtWidgets.QMenu('&Help', self)
        self.menuBar().addSeparator()
        self.menuBar().addMenu(self.help_menu)

        self.help_menu.addAction('&About', self.about)

        self.main_widget = QtWidgets.QWidget(self)

        l = QtWidgets.QVBoxLayout(self.main_widget)
        sc = MyStaticMplCanvas(self.main_widget, width=5, height=4, dpi=100)
        dc = MyDynamicMplCanvas(self.main_widget, width=5, height=4, dpi=100)
        l.addWidget(sc)
        l.addWidget(dc)

        self.main_widget.setFocus()
        self.setCentralWidget(self.main_widget)

        self.statusBar().showMessage("All hail matplotlib!", 2000)

    def fileQuit(self):
        self.close()

    def closeEvent(self, ce):
        self.fileQuit()

    def about(self):
        QtWidgets.QMessageBox.about(self, "About",
                                    """embedding_in_qt5.py example
Copyright 2005 Florent Rougon, 2006 Darren Dale, 2015 Jens H Nielsen

This program is a simple example of a Qt5 application embedding matplotlib
canvases.

It may be used and modified with no restriction; raw copies as well as
modified versions may be distributed without limitation.

This is modified from the embedding in qt4 example to show the difference
between qt4 and qt5""")

程式碼解析

通過matplotlib.use('Qt5Agg'),這行程式碼宣告matplotlib將要嵌入到pyqt5中,同樣通過這句,也可以宣告將matplotlib嵌入到其他的,gui介面中去,然後通過繼承FigureCanvas類來獲得一個即使widget的類也是FigureCanva類的類,然後通過self.fig成員,生成一個繪圖類,並由其建立一個繪圖佈局,返回一個self.axes來管理繪圖佈局中的內容。座標軸,標題,標籤,圖形樣式(餅圖,柱狀圖,折線圖等)等等的設定都通過self.axes的成員函式來設定完成。剛開始的使用還是比較雲裡霧裡的,現在就差不多了。我對官方例程做了些修改,具體的程式碼,可以到我的GitHub倉儲上檢視Qt-learn-pyqt5-matplotlib裡面也有一些其他的例子,應該還會不定期的更新,有興趣也可以看看。下面只需要對這幾個類進行例項話,開啟qt的事件迴圈就可以看到介面了,具體的可以看我的github程式碼,這裡就不多說了。

寫在最後

因為自身能力有限,也不是科班出身,都是自學的,目前還是一名學生,所以有未盡之處還請指正,不喜勿噴。謝謝。

相關文章