在pyqt中使用matplotlib

 

基本思路

  1. FigureCanvas→MyFigureCanvas
  2. FigureCanvas→MyFigureCanvas→QGraphicScene→QGraphicView

以下有展示三个例子,其中第二个仅供对比参考。

前两个例子不同之处是:第二个例子是吧FigureCanvas放到QGraphicScene中,再把QGraphicScene放到QGraphicView中,所做的图不能随着窗口的变化而变化;而第一个例子可以做到。

第三个例子是一个应用实例:给定主频并画出Ricker子波,运行的图如上所示。

仍然存在的问题是:第一个例子中,窗口缩小一定程度之后,所做的图会有一部分被遮挡

Example 1/3

import os, sys
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QIcon
from PyQt5.QtWidgets import *
import numpy as np

import matplotlib
matplotlib.use("Qt5Agg")
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.figure import Figure
import matplotlib.pyplot as mplot

class MyFigureCanvas(FigureCanvas): 
    def __init__(self):
        fig = Figure()  
        FigureCanvas.__init__(self, fig)
        self.axes = fig.add_subplot(111) 
        x=np.linspace(-10,10,1000)
        y=np.sin(x)
        self.axes.plot(x,y)
        self.axes.set_title('Example matplotlib in PyQt5' )
        self.axes.set_xlabel('X(m)')
        self.axes.set_ylabel('Y(m)')
        self.axes.grid()
        self.draw()

class MainWindow(QWidget):
    def __init__(self):
        super().__init__()
        self.initUI()

    def initUI(self):
        self.plot=MyFigureCanvas()
        self.buttonClose = QPushButton('Press to close this window')
        self.buttonClose.clicked.connect(self.close)
        layout = QVBoxLayout()
        layout.addWidget(self.plot)
        layout.addWidget(self.buttonClose)
        self.setLayout(layout)
        self.show()
        
if __name__ == '__main__':
    app = QApplication(sys.argv)
    mainwindow = MainWindow()
    sys.exit(app.exec_())

Example 2/3

注意:self.fig.draw()的作用

import os, sys
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QIcon
from PyQt5.QtWidgets import *
import numpy as np

import matplotlib
matplotlib.use("Qt5Agg")
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.figure import Figure
import matplotlib.pyplot as mplot

class MyFigureCanvas(FigureCanvas): 
    def __init__(self):
        fig = Figure()  
        FigureCanvas.__init__(self, fig)
        self.axes = fig.add_subplot(111) 
        #FigureCanvas.setSizePolicy(self,QSizePolicy.Expanding,QSizePolicy.Expanding)#?
        #PyQt5.QtWidgets.QSizePolicy
        #FigureCanvas.updateGeometry(self) #??

class MainWindow(QWidget):
    def __init__(self):
        super().__init__()
        self.initUI()

    def initUI(self):
        self.buttonPlot = QPushButton('Press to plot')
        self.buttonPlot.clicked.connect(self.slot_plot)

        self.graphicView = QGraphicsView()
        self.fig = MyFigureCanvas() 
        self.graphicScene = QGraphicsScene()  
        self.graphicScene.addWidget(self.fig)
        self.graphicView.setScene(self.graphicScene) 

        self.buttonClose = QPushButton('Press to close this window')
        self.buttonClose.clicked.connect(self.close)

        layout = QVBoxLayout()
        layout.addWidget(self.buttonPlot)
        layout.addWidget(self.graphicView)
        layout.addWidget(self.buttonClose)
        self.setLayout(layout)
        self.show()

    def slot_plot(self):
        x=np.linspace(-10,10,1000)
        y=np.sin(x)
        self.fig.axes.plot(x,y)
        self.fig.axes.set_title('Example matplotlib in PyQt5' )
        self.fig.axes.set_xlabel('X(m)')
        self.fig.axes.set_ylabel('Y(m)')
        self.fig.axes.grid()
        self.fig.draw()
        
if __name__ == '__main__':
    app = QApplication(sys.argv)
    mainwindow = MainWindow()
    sys.exit(app.exec_())

Example 3/3

import os, sys, shutil, math
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
import numpy as np

import matplotlib
matplotlib.use("Qt5Agg") 
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.figure import Figure
import matplotlib.pyplot as mplot

class PlotWavelet(FigureCanvas):  
    def __init__(self):
        self.fig = Figure() #linewidth=1
        FigureCanvas.__init__(self, self.fig)
        #self.axes = self.fig.add_subplot(111)
    def setData(x,y):
        self.x = x
        self.y = y
    def plot(self,x,y,title,xlabel,ylabel):
        self.axes.plot(x,y)
        self.axes.set_title(title )
        self.axes.set_xlabel(xlabel)
        self.axes.set_ylabel(ylabel)
        self.axes.grid()
        self.draw()
    def reset(self):
        self.fig.clear()
        self.axes = self.fig.add_subplot(111)

class WaveletDialog(QDialog):
    def __init__(self):
        super().__init__()
        self.initUI()

    def initUI(self):
        #==================================================
        # parameters
        layoutPara = QHBoxLayout()

        self.labelFreq = QLabel('Freq(Hz):')
        self.lineeditFreq = QLineEdit('30')
        self.lineeditFreq.editingFinished.connect(self.update)#textChanged not ok

        layoutPara.addWidget(self.labelFreq)
        layoutPara.addWidget(self.lineeditFreq)
        layoutPara.addStretch(1)

        self.labelTstart = QLabel('t_start(ms):')
        self.lineeditTstart = QLineEdit()
        self.lineeditTstart.setReadOnly(True)
        layoutPara.addWidget(self.labelTstart)
        layoutPara.addWidget(self.lineeditTstart)
        layoutPara.addStretch(1)

        self.labelTend = QLabel('t_end(ms):')
        self.lineeditTend = QLineEdit()
        self.lineeditTend.setReadOnly(True)
        layoutPara.addWidget(self.labelTend)
        layoutPara.addWidget(self.lineeditTend)
        layoutPara.addStretch(1)

        self.labelDt = QLabel('dt(ms):')
        self.lineeditDt = QLineEdit('1')
        layoutPara.addWidget(self.labelDt)
        layoutPara.addWidget(self.lineeditDt)

        #==================================================
        # figure-1: wave
        self.plotWave = PlotWavelet()

        #==================================================
        # put figures into layout
        layoutPaintCol = QVBoxLayout()
        layoutPaintCol.addWidget(self.plotWave)

        #==================================================
        # ok and cancel
        buttonOK = QPushButton('OK')
        buttonCancel = QPushButton('Cancel')
        buttonCancel.clicked.connect(self.close)

        layoutOkCancel = QHBoxLayout()
        layoutOkCancel.addStretch(1)
        layoutOkCancel.addWidget(buttonOK)
        layoutOkCancel.addWidget(buttonCancel)

        #==================================================
        # top layout 
        layoutTop = QVBoxLayout(self)
        layoutTop.addLayout(layoutPara)
        layoutTop.addLayout(layoutPaintCol)
        layoutTop.addLayout(layoutOkCancel)

        self.plot()

        self.resize(800,600)
        self.setWindowTitle('Wavelet')
        self.show()

    def update(self):
        self.plot()

    def plot(self):
        self.plotWave.reset()
        f = float(self.lineeditFreq.text())
        dt = 0.001*float(self.lineeditDt.text())
        Tms = int(math.ceil(1.0/f*10)*100.0)
        tstart = -Tms
        tend   = Tms
        self.lineeditTstart.setText(str(tstart))
        self.lineeditTend.setText(str(tend))

        tstart = tstart*0.001
        tend = tend*0.001
        t = tend - tstart
        n = int(t/dt)+1
        
        x = [tstart+dt*i for i in range(n)]
        y = np.sin(x)
        pi = np.pi
        y = [(1-2*pi*pi*x[i]*x[i]*f*f)*np.exp(-pi*pi*x[i]*x[i]*f*f) for i in range(n)]
        self.plotWave.plot(x,y,'Ricker Wavelet', 't(s)', 'amplitude')

if __name__ == '__main__':
    app = QApplication(sys.argv)
    test = WaveletDialog()
    #test.exec_()
    sys.exit(app.exec_())

参考

https://matplotlib.org/examples/user_interfaces/embedding_in_qt5.html

https://www.cnblogs.com/hhh5460/p/4322652.html

https://www.cnblogs.com/laoniubile/p/5904817.html

  • 2
    点赞
  • 43
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值