Skip to main content
 首页 » 编程设计

python之在 pyqt5 gui 中嵌入 matplotlib 图

2024年09月03日31cyq1162

我正在使用 PyQt5 尝试为我的数据分析工具生成一个 GUI。我的问题是我不明白如何嵌入具有完整功能的 matplotlib 图。

所有关于 PyQt5 和如何嵌入 matplotlib 的教程都展示了一种非常简单的方法,他们直接在代码中创建所有图形对象。我不想那样做,因为我的 GUI 是用 Qt Designer 生成的。我创建了一个 QWidget 来绘制其中的数据。因此,我在代码中导入了 UI 文件:

#!/usr/bin/env python3 
# -*- coding: utf-8 -*- 
 
import sys 
import numpy as np 
 
from PyQt5.QtGui import QPixmap 
from PyQt5 import QtCore, QtWidgets 
from PyQt5.QtWidgets import QMainWindow, QLabel, QGridLayout, QWidget, QTableWidget, QTableWidgetItem 
from PyQt5.QtWidgets import QApplication, QWidget, QInputDialog, QLineEdit, QFileDialog 
from PyQt5.QtWidgets import QPushButton 
from PyQt5.QtCore import QSize 
from PyQt5 import QtCore, QtGui, uic 
 
import matplotlib 
matplotlib.use('QT5Agg') 
 
import matplotlib.pylab as plt 
 
from matplotlib.backends.qt_compat import QtCore, QtWidgets, is_pyqt5 
from matplotlib.backends.backend_qt5agg import FigureCanvas,     NavigationToolbar2QT as NavigationToolbar 
from matplotlib.figure import Figure 
 
class MyWindow(QMainWindow): 
    def __init__(self): 
 
        super(MyWindow, self).__init__() 
 
        self.ui = uic.loadUi('test.ui', self)  
 
        # test data 
        data = np.array([0.7,0.7,0.7,0.8,0.9,0.9,1.5,1.5,1.5,1.5])         
        fig, ax1 = plt.subplots() 
        bins = np.arange(0.6, 1.62, 0.02) 
        n1, bins1, patches1 = ax1.hist(data, bins, alpha=0.6, density=False, cumulative=False) 
 
        # plot 
        self.plotWidget = FigureCanvas(fig)         
 
        # add toolbar 
        self.addToolBar(QtCore.Qt.BottomToolBarArea, NavigationToolbar(self.plotWidget, self))         
 
    ######################################### 
 
    # show window 
    self.show()  
 
    ######################################### 
 
if __name__ == '__main__': 
 
    app = QtWidgets.QApplication(sys.argv) 
    window = MyWindow() 
    sys.exit(app.exec_()) 

这是 Qt Designer 创建的 test.ui 文件:

<?xml version="1.0" encoding="UTF-8"?> 
<ui version="4.0"> 
 <class>Form</class> 
 <widget class="QWidget" name="Form"> 
  <property name="geometry"> 
   <rect> 
    <x>0</x> 
    <y>0</y> 
    <width>772</width> 
    <height>650</height> 
   </rect> 
  </property> 
  <property name="windowTitle"> 
   <string>Form</string> 
  </property> 
  <widget class="QWidget" name="plotWidge" native="true"> 
   <property name="geometry"> 
    <rect> 
     <x>20</x> 
     <y>20</y> 
     <width>721</width> 
     <height>571</height> 
    </rect> 
   </property> 
  </widget> 
 </widget> 
 <resources/> 
 <connections/> 
</ui> 

发生的事情是我可以在我的窗口中看到一个工具栏,但现在是数据。我可以使用“保存”图标将绘图保存为图像。我认为我正在创建与我在 Qt Designer 中创建的对象不相关的小部件对象的第二个实例。

我该如何解决这个问题? 提前致谢!

请您参考如下方法:

我认为您在 Qt Designer 中创建了一个名为 plotWidge 的小部件并且正在执行 self.plotWidget = FigureCanvas(fig) 替换它(即使名称一致, Action 不是完成的),这样就不会引起混淆,在 Qt Designer 中将 plotWidge 更改为 content_plot 所以 plotWidget必须借助布局放置在 content_plot 中。

测试.ui

<?xml version="1.0" encoding="UTF-8"?> 
<ui version="4.0"> 
 <class>Form</class> 
 <widget class="QWidget" name="Form"> 
  <property name="geometry"> 
   <rect> 
    <x>0</x> 
    <y>0</y> 
    <width>772</width> 
    <height>650</height> 
   </rect> 
  </property> 
  <property name="windowTitle"> 
   <string>Form</string> 
  </property> 
  <widget class="QWidget" name="content_plot" native="true"> 
   <property name="geometry"> 
    <rect> 
     <x>20</x> 
     <y>20</y> 
     <width>721</width> 
     <height>571</height> 
    </rect> 
   </property> 
  </widget> 
 </widget> 
 <resources/> 
 <connections/> 
</ui> 

*.py

import sys 
import numpy as np 
 
from PyQt5 import QtCore, QtWidgets, uic 
 
import matplotlib 
matplotlib.use('QT5Agg') 
 
import matplotlib.pylab as plt 
from matplotlib.backends.backend_qt5agg import FigureCanvas  
from matplotlib.backends.backend_qt5agg import NavigationToolbar2QT as NavigationToolbar 
 
class MyWindow(QtWidgets.QMainWindow): 
    def __init__(self): 
        super(MyWindow, self).__init__() 
        uic.loadUi('test.ui', self)  
        # test data 
        data = np.array([0.7,0.7,0.7,0.8,0.9,0.9,1.5,1.5,1.5,1.5])         
        fig, ax1 = plt.subplots() 
        bins = np.arange(0.6, 1.62, 0.02) 
        n1, bins1, patches1 = ax1.hist(data, bins, alpha=0.6, density=False, cumulative=False) 
        # plot 
        self.plotWidget = FigureCanvas(fig) 
        lay = QtWidgets.QVBoxLayout(self.content_plot)   
        lay.setContentsMargins(0, 0, 0, 0)       
        lay.addWidget(self.plotWidget) 
        # add toolbar 
        self.addToolBar(QtCore.Qt.BottomToolBarArea, NavigationToolbar(self.plotWidget, self)) 
 
if __name__ == '__main__': 
 
    app = QtWidgets.QApplication(sys.argv) 
    window = MyWindow() 
    window.show() 
    sys.exit(app.exec_())