将 Seaborn 图形放置在 Pyqt5 小部件中

Placing a Seaborn figure within a Pyqt5 Widget

我想将 3 个使用 seaborn 制作的图形放置在我在 pyQT 设计器中创建的 3 个不同的 pyQT 小部件中,这些图形是通过字典从不同 python 文件中的不同函数传递的。我将 post 我的代码在下面并进一步说明:

from PyQt5 import QtCore, QtGui, QtWidgets

class Ui_MainWindow(object):
    def setupUi(self, MainWindow):

        glycerate_PT_Graphs = glycerate_PT.get_PT() #get dictionary of graphs

        fig1 = glycerate_PT_Graphs['Level 1'] 
        fig2 = glycerate_PT_Graphs['Level 2']
        fig3 = glycerate_PT_Graphs['Level 3']

        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(1150, 771)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.Level1 = QtWidgets.QWidget(self.centralwidget)    #How to make this object a graph/figure?
        self.Level1.setGeometry(QtCore.QRect(520, 90, 241, 131))
        self.Level1.setObjectName("Level1")
        self.Level2 = QtWidgets.QWidget(self.centralwidget)
        self.Level2.setGeometry(QtCore.QRect(520, 250, 241, 121))
        self.Level2.setObjectName("Level2")
        self.Level3 = QtWidgets.QWidget(self.centralwidget)
        self.Level3.setGeometry(QtCore.QRect(520, 390, 241, 131))
        self.Level3.setObjectName("Level3")
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 1150, 20))
        self.menubar.setObjectName("menubar")
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))

此外,这是字典中存储的内容。

    def graph_PrecisionTotal(self, key, df):
        sns.set_style('darkgrid')
        fig, ax = plt.subplots()
        ax = sns.boxplot(x='Date', y='Calculated Concentration', data=df, width=0.2, whis=10)
        ax.set_title(str(self.analyte_name) + ' ' + key)
        fig = ax.get_figure()
        self.QCgraphs[key] = fig

我只想将这些 'self.Level1'、'self.Level2' 和 'self.Level3' QtWidget 对象作为 seaborn 图形。我怎样才能做到这一点?

你应该考虑:

  • 不要修改Qt Designer生成的class,所以必须去掉setupUi中的glycerate_PT_Graphs代码。在我的演示中,pyuic 生成的文件名为 gui.py
  • 如果您打算在 PyQt 中使用 matplotlib,那么您必须使用 FigureCanvas(参见 the official tutorial)
  • Seaborn 方法有一个参数 ax,其中传递了 canvas 的 ax。
from PyQt5 import QtCore, QtGui, QtWidgets

from matplotlib.backends.backend_qt5agg import FigureCanvas
from matplotlib.figure import Figure

import seaborn as sns

from gui import Ui_MainWindow


class MainWindow(QtWidgets.QMainWindow):
    def __init__(self, parent=None):
        super().__init__(parent)

        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)

        sns.set_theme(style="darkgrid")
        tips = sns.load_dataset("tips")

        self.plot(self.ui.Level1, tips, "plot1")
        self.plot(self.ui.Level2, tips, "plot2")
        self.plot(self.ui.Level3, tips, "plot3")

    def plot(self, widget, df, title):
        canvas = FigureCanvas(Figure())
        ax = canvas.figure.subplots()
        sns.boxplot(ax=ax, x="day", y="total_bill", data=df, width=0.2, whis=10)
        ax.set_title(title)
        lay = QtWidgets.QVBoxLayout(widget)
        lay.addWidget(canvas)
        canvas.draw()
        return canvas


if __name__ == "__main__":
    app = QtWidgets.QApplication([])
    w = MainWindow()
    w.show()
    app.exec_()