如何使用Matplotlib和PyQt5从CSV文件绘图

问题描述 投票:0回答:1

我正在尝试将此代码改编为PyQt5(来源:http://songhuiming.github.io/pages/2016/05/31/read-in-csv-and-plot-with-matplotlib-in-pyqt4/

from PyQt5 import QtGui,QtWidgets
import sys
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from matplotlib import style
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas

style.use('ggplot')


class PrettyWidget(QtWidgets.QMainWindow):


    def __init__(self):
        super().__init__()
        #super(PrettyWidget, self).__init__()
        self.initUI()

    def initUI(self):
        self.setGeometry(600,300, 1000, 600)
        self.center()
        self.setWindowTitle('Revision on Plots, Tables and File Browser')     
        #Grid Layout
        grid = QtWidgets.QGridLayout()
        self.setLayout(grid)

        #Import CSV Button
        btn1 = QtWidgets.QPushButton('Import CSV', self)
        btn1.resize(btn1.sizeHint())
        btn1.clicked.connect(self.getCSV)
        grid.addWidget(btn1, 1, 0)



        #Canvas and Toolbar
        self.figure = plt.figure(figsize=(15,5))    
        self.canvas = FigureCanvas(self.figure)     
        grid.addWidget(self.canvas, 2,0,1,2)


        #DropDown mean / comboBox

        self.df = pd.DataFrame()
        self.rating_list = []
        self.yq_list = []

        self.comboBox = QtWidgets.QComboBox(self)
        self.comboBox.addItems(self.rating_list)
        grid.addWidget(self.comboBox, 0, 0)

        self.comboBox2 = QtWidgets.QComboBox(self)
        self.comboBox2.addItems(self.yq_list)
        grid.addWidget(self.comboBox2, 0, 1)

        #Plot Button
        btn2 = QtWidgets.QPushButton('Plot', self)
        btn2.resize(btn2.sizeHint())    
        btn2.clicked.connect(self.plot)
        grid.addWidget(btn2, 1, 1)

        self.show()


    def getCSV(self):
        filePath = QtWidgets.QFileDialog.getOpenFileName(self, 'Open file', '/home')
        print (filePath)
        self.df = pd.read_csv(str(filePath))
        self.rating_list = self.df.rating.unique().tolist()
        self.yq_list = [str(x) for x in self.df.yq.unique().tolist()]       
        self.comboBox.addItems(self.rating_list)
        self.comboBox2.addItems(self.yq_list)
        print (self.rating_list)


    def plot(self):
        y = []
        for n in range(3):
            try:
                y.append(self.table.item(0, n).text())
            except:
                y.append(np.nan)

        p1 = self.df.ix[(self.df.rating ==  str(self.comboBox.currentText())) & (self.df.yq ==  int(str(self.comboBox2.currentText()))), :]
        print (p1)

        plt.cla()


        ax = self.figure.add_subplot(111)
        ax.plot(p1.ix[:, 0], 'g', label = "Pred on data with Model")
        ax.plot(p1.ix[:, 1], label = "adj Pred to non-decreasing")
        ax.plot(p1.ix[:, 3], label = "Fitting value in Model")
        ax.plot(p1.ix[:, 2], 'r', label = "Actual PD")
        ax.plot(p1.ix[:, 4], 'y', label = "Long Run Avg")

        ax.set_title('Canada C&I PD Plot')
        ax.legend(loc = 0)
        self.canvas.draw()


    def center(self):
        qr = self.frameGeometry()
        cp = QtWidgets.QDesktopWidget().availableGeometry().center()
        qr.moveCenter(cp)
        self.move(qr.topLeft())



def main():
    app = QtWidgets.QApplication(sys.argv)
    w = PrettyWidget()
    sys.exit(app.exec_())


if __name__ == '__main__':
    main()

我收到了这个警告:QWidget :: setLayout:试图在PrettyWidget上设置QLayout“”,它已经有一个布局QCoreApplication :: exec:事件循环已经运行而且小部件也是重叠的,任何帮助都将是非常感谢!

python csv matplotlib pyqt pyqt5
1个回答
0
投票

QMainWindow是一个特殊的小部件,有一个特殊的设计,如下面的image所示:

enter image description here

因此,如果要添加布局,则必须在Central Widget中执行此操作,但在此之前,您必须通过setCentralWidget()方法创建Central Widget,如下所示:

class PrettyWidget(QtWidgets.QMainWindow):
    def __init__(self):
        [...]

    def initUI(self):
        self.setGeometry(600,300, 1000, 600)
        self.center()
        self.setWindowTitle('Revision on Plots, Tables and File Browser')     
        #Grid Layout
        grid = QtWidgets.QGridLayout()
        widget = QtWidgets.QWidget(self)
        self.setCentralWidget(widget)
        widget.setLayout(grid)

        #Import CSV Button
        [...]

更多:

您将遇到的另一个错误是在PyQt5中getOpenFileName()返回2个元素的元组,其中第一个是所选文件的名称,第二个是使用过的过滤器,此外它必须验证是否给出了选择你应该看到filePath与empty不同,如下所示:

def getCSV(self):
    filePath, _ = QtWidgets.QFileDialog.getOpenFileName(self, 'Open file', '/home')
    if filePath != "":
        print (filePath)
        self.df = pd.read_csv(str(filePath))
        self.rating_list = self.df.rating.unique().tolist()
        self.yq_list = [str(x) for x in self.df.yq.unique().tolist()]       
        self.comboBox.addItems(self.rating_list)
        self.comboBox2.addItems(self.yq_list)
        print (self.rating_list)
© www.soinside.com 2019 - 2024. All rights reserved.