简体   繁体   English

使用PyQt5进行实时绘图

[英]realtime plot using PyQt5

I want to build a program where we get updated data from interactive brokers (a popular online broker) and I want to update a plot in a simple pyqt5 interface. 我想构建一个程序,从交互式经纪人(一个流行的在线经纪人)那里获取更新的数据,我想在一个简单的pyqt5界面中更新一个地块。

The program sequence is the following: 程序顺序如下:

We start the Ui_MainWindow interface. 我们启动Ui_MainWindow接口。 If we click on pushbutton2 we initiate a thread with the function GetDataBackground . 如果单击pushbutton2GetDataBackground使用功能GetDataBackground启动线程。 This function uses the class GetData and every time there is an update of the data to plot, the function tickPrice and tickSize is executed. 该函数使用GetData类,并且每次有要绘制的数据更新时, tickSize执行tickPricetickSize函数。 In this step, I want to update the plot (for the moment it can be with random numbers like codded in the update_graph ). 在这一步中,我想更新绘图(目前可以使用诸如update_graph编码的随机数)。

When I run the program it returns the error: 当我运行程序时,它返回错误:

AttributeError: 'GetData' object has no attribute 'MplWidget'

Which seams that I do not have access to the main window. 我无法访问主窗口的接缝。

The code is the following: 代码如下:

from PyQt5 import QtCore, QtGui, QtWidgets   
from mplwidget import MplWidget
import threading    
import sys
sys.path.insert(0, "/Users/nuno/Desktop/IB_API/source/pythonclient/")   
from ibapi.client import EClient
from ibapi.wrapper import  EWrapper
from ibapi.contract import Contract
from ibapi.ticktype import TickTypeEnum
import numpy as np
import sys


class GetData(EWrapper, EClient):

    outrights = []
    calendars = []
    flies = []

    def __init__(self):
        EClient.__init__(self, self)

    def error(self, reqId, errorCode, errorString):
        print("Error: ", reqId, " ", errorCode, " ", errorString)

    def tickPrice(self, reqId , tickType, price, attrib):
        print("Tick Price. Ticker Id: ", reqId, "tickType: ", TickTypeEnum.to_str(tickType), " Price: ", price, end='\n')
        self.outrights[reqId][TickTypeEnum.to_str(tickType)] = price
        price = [x['DELAYED_LAST'] for x in self.outrights]
        print('Push button')
        self.testplot()
        self.update_graph()
        print(price)

    def tickSize(self, reqId, tickType, size):
        print("Tick Size. Ticker Id: ", reqId, "tickType: ", TickTypeEnum.to_str(tickType), 'Size: ', size)
        self.outrights[reqId][TickTypeEnum.to_str(tickType)] = size
        self.testplot()


    def testplot(self):
        print('Function correctly called')

    def update_graph(self):

        print('Push button')

        x = np.random.rand(30)
        y = np.random.rand(30)

        self.MplWidget.canvas.axes.clear()
        self.MplWidget.canvas.axes.plot(x, y)
        self.MplWidget.canvas.axes.legend(('random'), loc='upper right')
        self.MplWidget.canvas.draw()


def GetDataBackground():
    """
    This function gets the data in the background.

    :param PlotData:
    :return:
    """

    print('Interactive Brokers get data has started.')

    app = GetData()

    app.connect("127.0.0.1", 4002, 0)
    print("serverVersion: {} connectionTime: {}".format(app.serverVersion(), app.twsConnectionTime()))

    contract_list = ['GEZ0', 'GEH1', 'GEM1', 'GEU1', 'GEZ1', 'GEH2', 'GEM2', 'GEU2', 'GEZ2', 'GEH3', 'GEM3', 'GEU3',
                     'GEZ3', 'GEH4', 'GEM4', 'GEU4', 'GEZ4']

    # This for loop generates a list of dictionaries that live inside the class TestApp
    for i, contract in enumerate(contract_list):
        temp_dict = {}
        print(contract)
        temp_dict['localSymbol'] = contract
        temp_dict['tickerID'] = i
        temp_dict['DELAYED_ASK'] = None
        temp_dict['DELAYED_BID'] = None
        temp_dict['DELAYED_OPEN'] = None
        temp_dict['DELAYED_HIGH'] = None
        temp_dict['DELAYED_LOW'] = None
        temp_dict['DELAYED_CLOSE'] = None
        temp_dict['DELAYED_ASK_SIZE'] = None
        temp_dict['DELAYED_BID_SIZE'] = None
        temp_dict['DELAYED_VOLUME'] = None
        temp_dict['DELAYED_LAST'] = None
        temp_dict['DELAYED_LAST_SIZE'] = None
        app.outrights.append(temp_dict)

    contracts = [Contract() for x in contract_list]  # _

    for i in range(len(contract_list)):
        contracts[i].secType = 'FUT'
        contracts[i].exchange = 'GLOBEX'
        contracts[i].currency = 'USD'
        contracts[i].localSymbol = contract_list[i]

    app.reqMarketDataType(3)

    for i in range(len(contract_list)):
        print(contracts[i].localSymbol)
        app.reqMktData(i, contracts[i], "", False, False, [])

    app.run()

class Ui_MainWindow(GetData):

    def __init__(self):
        super().__init__()


    def start_download(self):
        download_info = threading.Thread(target = GetDataBackground)
        download_info.start()

    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(1280, 1024)

        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")

        self.pushButton = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton.setGeometry(QtCore.QRect(880, 80, 221, 32))
        self.pushButton.setObjectName("pushButton")

        self.pushButton2 = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton2.setGeometry(QtCore.QRect(880, 45, 221, 32))
        self.pushButton2.setObjectName("Get data")

        self.MplWidget = MplWidget(self.centralwidget)
        self.MplWidget.setGeometry(QtCore.QRect(49, 39, 771, 551))
        self.MplWidget.setObjectName("MplWidget")

        MainWindow.setCentralWidget(self.centralwidget)

        self.menubar = QtWidgets.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 1148, 22))
        self.menubar.setObjectName("menubar")

        self.menuFile = QtWidgets.QMenu(self.menubar)
        self.menuFile.setObjectName("menuFile")

        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)
        self.actionOpen = QtWidgets.QAction(MainWindow)
        self.actionOpen.setObjectName("actionOpen")
        self.actionSave = QtWidgets.QAction(MainWindow)
        self.actionSave.setObjectName("actionSave")
        self.actionClose = QtWidgets.QAction(MainWindow)
        self.actionClose.setObjectName("actionClose")
        self.actionSave_as = QtWidgets.QAction(MainWindow)
        self.actionSave_as.setObjectName("actionSave_as")
        self.menuFile.addSeparator()
        self.menuFile.addAction(self.actionOpen)
        self.menuFile.addAction(self.actionSave)
        self.menuFile.addAction(self.actionSave_as)
        self.menuFile.addSeparator()
        self.menuFile.addAction(self.actionClose)
        self.menubar.addAction(self.menuFile.menuAction())

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

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
        self.pushButton.setText(_translate("MainWindow", "PushButton"))
        self.pushButton2.setText(_translate("MainWindow", "GetData"))
        self.menuFile.setTitle(_translate("MainWindow", "File"))
        self.actionOpen.setText(_translate("MainWindow", "Open..."))
        self.actionSave.setText(_translate("MainWindow", "Save"))
        self.actionClose.setText(_translate("MainWindow", "Close"))
        self.actionSave_as.setText(_translate("MainWindow", "Save As..."))

        self.pushButton.clicked.connect(self.update_graph)
        self.pushButton2.clicked.connect(self.start_download)

if __name__ == "__main__":

    app = QtWidgets.QApplication(sys.argv)
    MainWindow = QtWidgets.QMainWindow()
    ui = Ui_MainWindow()
    ui.setupUi(MainWindow)
    MainWindow.show()
    sys.exit(app.exec_())

Please refer to: https://eli.thegreenplace.net/2009/01/20/matplotlib-with-pyqt-guis 请参考: https : //eli.thegreenplace.net/2009/01/20/matplotlib-with-pyqt-guis

This is an excellent example for matplotlib with PyQt GUIs 这是带有PyQt GUI的matplotlib的绝佳示例

Refer here too for more detailed example: https://github.com/eliben/code-for-blog/blob/master/2008/wx_mpl_dynamic_graph.py 对于更详细的示例,也请参见此处: https : //github.com/eliben/code-for-blog/blob/master/2008/wx_mpl_dynamic_graph.py

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM