pydata

Keep Looking, Don't Settle

read in csv and plot with matplotlib in PyQt4 02

跟第一版的区别: 1. 主窗口从QMainWindow继承过来,而不是从QWidget. 所有的控件加载在QWidget上,然后QWidget加载到QMainWindow

  1. 模块化一些产生控件的code. 比如create_menu, create_status_bar, create_main_framecreate_action等等

  2. 可以再添加QHBoxLayout或者QVBoxLayout来安排更多的widget

'''
20160531 in v4: try to re-arrange the widgets with QMainWindow

20160516: in v3, try to read in the csv file through menu rather than do this in the code, but v3 does not work

20160516: in v2, try to use dropdown menu to select data

20160515 in this v1, we can input the rating and year_quarter in the first and second cell of the table and then plot the result.
'''

from PyQt4 import QtGui, QtCore
import os, sys
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from matplotlib import style
from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas

style.use('ggplot')


class PrettyWidget(QtGui.QMainWindow):


    def __init__(self, parent = None):
        super(PrettyWidget, self).__init__(parent)
        self.setWindowTitle('Revision on Plots, Tables and File Browser')     

        self.create_menu()
        self.create_main_frame()
        self.create_status_bar()

    def create_main_frame(self):

        self.main_frame = QtGui.QWidget()

        #Grid Layout
        grid = QtGui.QGridLayout()
        self.setLayout(grid)

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


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

        #DropDown mean / comboBox

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

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

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

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

        self.main_frame.setLayout(grid)
        self.setCentralWidget(self.main_frame)

        self.show()

    def create_status_bar(self):
        self.status_text = QtGui.QLabel("Please load the csv file: ca_cni_camacro_20160531.csv!!")
        self.statusBar().addWidget(self.status_text, 1)

    def create_menu(self):
        self.file_menu = self.menuBar().addMenu("&File")
        open_action = self.create_action("&Open File", slot = lambda: self.on_about("Open CSV", "Please click Import CSV button"))
        quit_action = self.create_action("&Quit", slot = self.close, shortcut = "Ctrl+Q", tip = "Close the App")

        self.add_actions(self.file_menu, (open_action, None, quit_action))

        self.help_menu = self.menuBar().addMenu("&Help")
        about_action = self.create_action("&About", shortcut = 'F1', slot = lambda: self.on_about("About the App", "Demo of IFRS9 PD Plot"))

        self.add_actions(self.help_menu, (about_action, ))

    def on_about(self, msg_title, msg):
        QtGui.QMessageBox.about(self, msg_title, msg.strip())

    def add_actions(self, target, actions):
        for action in actions:
            if action is None:
                target.addSeparator()
            else:
                target.addAction(action)

    def create_action(self, text, slot = None, shortcut = None, icon = None, tip = None, checkable = False, signal = "triggered()"):
        action = QtGui.QAction(text, self)

        if icon is not None:
            action.setIcon(text, self)
        if shortcut is not None:
            action.setShortcut(shortcut)
        if tip is not None:
            action.setToolTip(tip)
            action.setStatusTip(tip)
        if slot is not None:
            self.connect(action, QtCore.SIGNAL(signal), slot)
        if checkable is not None:
            action.setCheckable(True)
        return action


    def getCSV(self):
        filePath = QtGui.QFileDialog.getOpenFileName(self,
                                                    'Single File',
                                                    '~/Desktop/PyRevolution/PyQt4',
                                                    '*.csv')
        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
        self.status_text.setText("Loaded " + str(filePath))


    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 = QtGui.QDesktopWidget().availableGeometry().center()
        qr.moveCenter(cp)
        self.move(qr.topLeft())



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


if __name__ == '__main__':
    main()

Figure 1. ready to read in csv png