[英]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
. 如果单击pushbutton2
, GetDataBackground
使用功能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
执行tickPrice
和tickSize
函数。 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.