From f1ba9f5b9bd9d542cbed86427db17cf7a2a9617d Mon Sep 17 00:00:00 2001 From: "Dr. Chandrakant Bangar" <127198654+DrChandrakant@users.noreply.github.com> Date: Wed, 21 Jun 2023 17:59:09 +0530 Subject: [PATCH 1/2] Example Added For Major GUI Packages Example Added For Major GUI Packages PySide6, PyQt5 and PyQt6 --- examples/gui_examples/PyQt5/pyqt5.py | 55 +++++++++++++++ examples/gui_examples/PyQt5/ui.py | 52 ++++++++++++++ examples/gui_examples/PyQt6/app.py | 14 ++++ examples/gui_examples/PyQt6/gui.py | 30 ++++++++ examples/gui_examples/PyQt6/plot_signal.py | 61 ++++++++++++++++ examples/gui_examples/PyQt6/ui_main_window.py | 45 ++++++++++++ examples/gui_examples/Pyside 6/app.py | 14 ++++ examples/gui_examples/Pyside 6/gui.py | 30 ++++++++ .../Pyside 6/main_window - Copy.ui | 65 +++++++++++++++++ examples/gui_examples/Pyside 6/plot_signal.py | 60 ++++++++++++++++ .../gui_examples/Pyside 6/ui_main_window.py | 70 +++++++++++++++++++ 11 files changed, 496 insertions(+) create mode 100644 examples/gui_examples/PyQt5/pyqt5.py create mode 100644 examples/gui_examples/PyQt5/ui.py create mode 100644 examples/gui_examples/PyQt6/app.py create mode 100644 examples/gui_examples/PyQt6/gui.py create mode 100644 examples/gui_examples/PyQt6/plot_signal.py create mode 100644 examples/gui_examples/PyQt6/ui_main_window.py create mode 100644 examples/gui_examples/Pyside 6/app.py create mode 100644 examples/gui_examples/Pyside 6/gui.py create mode 100644 examples/gui_examples/Pyside 6/main_window - Copy.ui create mode 100644 examples/gui_examples/Pyside 6/plot_signal.py create mode 100644 examples/gui_examples/Pyside 6/ui_main_window.py diff --git a/examples/gui_examples/PyQt5/pyqt5.py b/examples/gui_examples/PyQt5/pyqt5.py new file mode 100644 index 00000000..596aabc3 --- /dev/null +++ b/examples/gui_examples/PyQt5/pyqt5.py @@ -0,0 +1,55 @@ +import sys +from PyQt5.QtWidgets import QApplication, QMainWindow, QPushButton, QVBoxLayout,QWidget +import matplotlib +matplotlib.use('Qt5Agg') +from matplotlib.backends.backend_qt5agg import ( FigureCanvasQTAgg as FigureCanvas, NavigationToolbar2QT as NavigationToolbar) +import mplfinance as mpl +import pandas as pd + +class MainWindow(QMainWindow): + def __init__(self): + super().__init__() + self.setWindowTitle("PyQt5 Mplfinance Example") + + button = QPushButton("Plot", self) + button.clicked.connect(self.on_button_click) + + def on_button_click(self): + self.figure, axlist = plot(self) + canvas = FigureCanvas(self.figure) + layout = QVBoxLayout() + toolbar = NavigationToolbar(canvas) + layout.addWidget(canvas) + layout.addWidget(toolbar) + widget = QWidget() + + widget.setLayout(layout) + self.setCentralWidget(widget) + +def plot(self): + idf = pd.read_csv('examples/data/SPY_20110701_20120630_Bollinger.csv',index_col=0,parse_dates=True) + df = idf.loc['2011-07-01':'2011-12-30',:] + fig, axlist = mpl.plot( + df, + returnfig= True, + tight_layout= True, + figsize =(4,4), + style = 'yahoo', + type = 'candle', + scale_padding=0.25, + ) + axlist[0].xaxis.set_tick_params(labelsize=5) + axlist[0].yaxis.set_tick_params(labelsize=5) + return fig, axlist[0] + + +if __name__ == "__main__": + app = QApplication(sys.argv) + window = MainWindow() + window.show() + sys.exit(app.exec()) + + + + + diff --git a/examples/gui_examples/PyQt5/ui.py b/examples/gui_examples/PyQt5/ui.py new file mode 100644 index 00000000..c87ee3ff --- /dev/null +++ b/examples/gui_examples/PyQt5/ui.py @@ -0,0 +1,52 @@ +# -*- coding: utf-8 -*- + +################################################################################ +## Form generated from reading UI file 'uiAHaQBa.ui' +## +## Created by: Qt User Interface Compiler version 6.4.3 +## +## WARNING! All changes made in this file will be lost when recompiling UI file! +################################################################################ + +from PySide6.QtCore import (QCoreApplication, QDate, QDateTime, QLocale, + QMetaObject, QObject, QPoint, QRect, + QSize, QTime, QUrl, Qt) +from PySide6.QtGui import (QBrush, QColor, QConicalGradient, QCursor, + QFont, QFontDatabase, QGradient, QIcon, + QImage, QKeySequence, QLinearGradient, QPainter, + QPalette, QPixmap, QRadialGradient, QTransform) +from PySide6.QtWidgets import (QApplication, QMainWindow, QMenuBar, QPushButton, + QSizePolicy, QStatusBar, QWidget) + +class Ui_MainWindow(object): + def setupUi(self, MainWindow): + if not MainWindow.objectName(): + MainWindow.setObjectName(u"MainWindow") + MainWindow.resize(786, 366) + self.centralwidget = QWidget(MainWindow) + self.centralwidget.setObjectName(u"centralwidget") + self.widget = QWidget(self.centralwidget) + self.widget.setObjectName(u"widget") + self.widget.setGeometry(QRect(10, 0, 541, 341)) + self.pushButton = QPushButton(self.centralwidget) + self.pushButton.setObjectName(u"pushButton") + self.pushButton.setGeometry(QRect(620, 140, 75, 24)) + MainWindow.setCentralWidget(self.centralwidget) + self.menubar = QMenuBar(MainWindow) + self.menubar.setObjectName(u"menubar") + self.menubar.setGeometry(QRect(0, 0, 786, 22)) + MainWindow.setMenuBar(self.menubar) + self.statusbar = QStatusBar(MainWindow) + self.statusbar.setObjectName(u"statusbar") + MainWindow.setStatusBar(self.statusbar) + + self.retranslateUi(MainWindow) + + QMetaObject.connectSlotsByName(MainWindow) + # setupUi + + def retranslateUi(self, MainWindow): + MainWindow.setWindowTitle(QCoreApplication.translate("MainWindow", u"MainWindow", None)) + self.pushButton.setText(QCoreApplication.translate("MainWindow", u"PushButton", None)) + # retranslateUi + diff --git a/examples/gui_examples/PyQt6/app.py b/examples/gui_examples/PyQt6/app.py new file mode 100644 index 00000000..ea516f65 --- /dev/null +++ b/examples/gui_examples/PyQt6/app.py @@ -0,0 +1,14 @@ +import sys +# Import 'QApplication' from PyQt6 For Create Empty App With PyQt6 +from PyQt6.QtWidgets import QApplication +# gui is file Where We Creating GUI Component Such As Button And Layout +from gui import MainWindow + +if __name__ == "__main__": + # sys.argv Created App Will Recieved Mouse and Keep Board Inputs + app = QApplication(sys.argv) + # Create Main Window of App + window = MainWindow() + # Show Main Window of App + window.show() + sys.exit(app.exec()) \ No newline at end of file diff --git a/examples/gui_examples/PyQt6/gui.py b/examples/gui_examples/PyQt6/gui.py new file mode 100644 index 00000000..bf1116bc --- /dev/null +++ b/examples/gui_examples/PyQt6/gui.py @@ -0,0 +1,30 @@ +# import UI `ui_main_window` From QT Designer Call UI_MainWindow +from ui_main_window import Ui_MainWindow +# import PyQt6 > QtWidgets > QMainWindow +from PyQt6.QtWidgets import QMainWindow +# import plot_signal.py Where We Working Qthread, mplfinance, mataplotlib +import plot_signal + + +class MainWindow(QMainWindow): + def __init__(self,*args,): + super(MainWindow, self).__init__(*args,) + # imported UI set as self.ui + self.ui = Ui_MainWindow() + self.ui.setupUi(self) + # Title Set + self.setWindowTitle("PySide6 Mplfinance Example") + #UI Button Linked to Function chart_plot_im + self.ui.plot.clicked.connect(self.chart_plot_im) + + def chart_plot_im(self): + # Use of Qthread plot_signal.py + self.temp_thread = plot_signal.ChartThread(self) + # Signal Generated From Qthread Send To UI part with function handleFigureReady + self.temp_thread.figureReady.connect(self.handleFigureReady) + self.temp_thread.start() + + def handleFigureReady(self, figure): + plot_signal.ChartWidget.updateChart(self,figure) + + diff --git a/examples/gui_examples/PyQt6/plot_signal.py b/examples/gui_examples/PyQt6/plot_signal.py new file mode 100644 index 00000000..8f0c3754 --- /dev/null +++ b/examples/gui_examples/PyQt6/plot_signal.py @@ -0,0 +1,61 @@ +from PyQt6.QtWidgets import QWidget + +from PyQt6.QtCore import QThread, pyqtSignal +import matplotlib +matplotlib.use('Qt5Agg') +from matplotlib.backends.backend_qt5agg import ( FigureCanvasQTAgg as FigureCanvas, NavigationToolbar2QT as NavigationToolbar) +import mplfinance as mpl +import pandas as pd + + +class ChartWidget(QWidget): + def __init__(self,main_window,item): + super().__init__() + #Main Window Assign + self.main_window = main_window + + def updateChart(self,figure_in): + # Generating Canvas Which Hold Our Plot + self.canvas = FigureCanvas(figure_in) + # Generating Matplot toolbar + toolbar = NavigationToolbar(self.canvas) + # Seting Canvas TO Layout + self.ui.horizontalLayout.addWidget(self.canvas) + # Seting Toolbar To Layout + #self.ui.horizontalLayout.addWidget(toolbar) + self.canvas.draw() + + + +class ChartThread(QThread): + # Major Difference PySide6 and PyQt6 is pyqtsignal and signal + figureReady = pyqtSignal(object) + _name = '' + + def __init__(self,main_window): + super().__init__() + self.main_window = main_window + + def run(self): + #Figure Return Here + self.figure, self.ax = plot(self.main_window) + # Figure Sending To Main Window With Signal + self.figureReady.emit(self.figure) + + +def plot(self): + # OHLCV Data + idf = pd.read_csv('examples/data/SPY_20110701_20120630_Bollinger.csv',index_col=0,parse_dates=True) + df = idf.loc['2011-07-01':'2011-12-30',:] + fig, axlist = mpl.plot( + df, + returnfig= True, + tight_layout= True, + figsize =(4,4), + style = 'yahoo', + type = 'candle', + scale_padding=0.25, + ) + axlist[0].xaxis.set_tick_params(labelsize=5) + axlist[0].yaxis.set_tick_params(labelsize=5) + return fig, axlist[0] \ No newline at end of file diff --git a/examples/gui_examples/PyQt6/ui_main_window.py b/examples/gui_examples/PyQt6/ui_main_window.py new file mode 100644 index 00000000..559967d6 --- /dev/null +++ b/examples/gui_examples/PyQt6/ui_main_window.py @@ -0,0 +1,45 @@ +# -*- coding: utf-8 -*- + +################################################################################ +## Form generated from reading UI file 'main_window - CopyJfgUiT.ui' +## +## Created by: Qt User Interface Compiler version 6.4.3 +## +## WARNING! All changes made in this file will be lost when recompiling UI file! +################################################################################ + +from PyQt6.QtCore import (QCoreApplication, QDate, QDateTime, QLocale, + QMetaObject, QObject, QPoint, QRect, + QSize, QTime, QUrl, Qt) +from PyQt6.QtGui import (QAction, QBrush, QColor, QConicalGradient, + QCursor, QFont, QFontDatabase, QGradient, + QIcon, QImage, QKeySequence, QLinearGradient, + QPainter, QPalette, QPixmap, QRadialGradient, + QTransform) +from PyQt6.QtWidgets import (QApplication, QHBoxLayout, QMainWindow, QPushButton, + QSizePolicy, QWidget,QSizePolicy) + +class Ui_MainWindow(object): + def setupUi(self, MainWindow): + if not MainWindow.objectName(): + MainWindow.setObjectName(u"MainWindow") + MainWindow.resize(724, 472) + + self.centralwidget = QWidget(MainWindow) + self.centralwidget.setObjectName(u"centralwidget") + self.horizontalLayoutWidget = QWidget(self.centralwidget) + self.horizontalLayoutWidget.setObjectName(u"horizontalLayoutWidget") + self.horizontalLayoutWidget.setGeometry(QRect(9, 9, 571, 461)) + self.horizontalLayout = QHBoxLayout(self.horizontalLayoutWidget) + self.horizontalLayout.setObjectName(u"horizontalLayout") + self.horizontalLayout.setContentsMargins(0, 0, 0, 0) + self.plot = QPushButton(self.centralwidget) + self.plot.setObjectName(u"plot") + self.plot.setGeometry(QRect(610, 220, 75, 24)) + MainWindow.setCentralWidget(self.centralwidget) + + def retranslateUi(self, MainWindow): + + self.plot.setText(QCoreApplication.translate("MainWindow", u"plot", None)) + # retranslateUi + diff --git a/examples/gui_examples/Pyside 6/app.py b/examples/gui_examples/Pyside 6/app.py new file mode 100644 index 00000000..9f693ec2 --- /dev/null +++ b/examples/gui_examples/Pyside 6/app.py @@ -0,0 +1,14 @@ +import sys +# Import 'QApplication' from PySide 6 For Create Empty App With PySide6 +from PySide6.QtWidgets import QApplication +# gui is file Where We Creating GUI Component Such As Button And Layout +from gui import MainWindow + +if __name__ == "__main__": + # sys.argv Created App Will Recieved Mouse and Keep Board Inputs + app = QApplication(sys.argv) + # Create Main Window of App + window = MainWindow() + # Show Main Window of App + window.show() + sys.exit(app.exec()) \ No newline at end of file diff --git a/examples/gui_examples/Pyside 6/gui.py b/examples/gui_examples/Pyside 6/gui.py new file mode 100644 index 00000000..53ea3fc1 --- /dev/null +++ b/examples/gui_examples/Pyside 6/gui.py @@ -0,0 +1,30 @@ +# import UI `ui_main_window` From QT Designer Call UI_MainWindow +from ui_main_window import Ui_MainWindow +# import Pyside6 > QtWidgets > QMainWindow +from PySide6.QtWidgets import QMainWindow +# import plot_signal.py Where We Working Qthread, mplfinance, mataplotlib +import plot_signal + + +class MainWindow(QMainWindow): + def __init__(self): + super(MainWindow, self).__init__() + # imported UI set as self.ui + self.ui = Ui_MainWindow() + self.ui.setupUi(self) + # Title Set + self.setWindowTitle("PySide6 Mplfinance Example") + #UI Button Linked to Function chart_plot_im + self.ui.plot.clicked.connect(self.chart_plot_im) + + def chart_plot_im(self): + # Use of Qthread plot_signal.py + self.temp_thread = plot_signal.ChartThread(self) + # Signal Generated From Qthread Send To UI part with function handleFigureReady + self.temp_thread.figureReady.connect(self.handleFigureReady) + self.temp_thread.start() + + def handleFigureReady(self, figure): + plot_signal.ChartWidget.updateChart(self,figure) + + diff --git a/examples/gui_examples/Pyside 6/main_window - Copy.ui b/examples/gui_examples/Pyside 6/main_window - Copy.ui new file mode 100644 index 00000000..010570fe --- /dev/null +++ b/examples/gui_examples/Pyside 6/main_window - Copy.ui @@ -0,0 +1,65 @@ + + + MainWindow + + + Qt::NonModal + + + + 0 + 0 + 697 + 447 + + + + + 0 + 0 + + + + Market Insight + + + + + + + QLayout::SetFixedSize + + + + + + + QLayout::SetFixedSize + + + + + + 0 + 0 + + + + + 115 + 24 + + + + plot + + + + + + + + + + + diff --git a/examples/gui_examples/Pyside 6/plot_signal.py b/examples/gui_examples/Pyside 6/plot_signal.py new file mode 100644 index 00000000..bb77e93b --- /dev/null +++ b/examples/gui_examples/Pyside 6/plot_signal.py @@ -0,0 +1,60 @@ +from PySide6.QtWidgets import * +from PySide6.QtCore import QThread, Signal +import matplotlib +matplotlib.use('Qt5Agg') +from matplotlib.backends.backend_qt5agg import ( FigureCanvasQTAgg as FigureCanvas, NavigationToolbar2QT as NavigationToolbar) +import mplfinance as mpl +import pandas as pd + + +class ChartWidget(QWidget): + def __init__(self,main_window,item): + super().__init__() + #Main Window Assign + self.main_window = main_window + + def updateChart(self,figure_in): + # Generating Canvas Which Hold Our Plot + self.canvas = FigureCanvas(figure_in) + # Generating Matplot toolbar + toolbar = NavigationToolbar(self.canvas) + # Seting Canvas TO Layout + self.ui.horizontalLayout.addWidget(self.canvas) + # Seting Toolbar To Layout + #self.ui.horizontalLayout.addWidget(toolbar) + self.canvas.draw() + + + +class ChartThread(QThread): + # Major Difference PySide6 and PyQt6 is pysignal and signal + figureReady = Signal(object) + _name = '' + + def __init__(self,main_window): + super().__init__() + self.main_window = main_window + + def run(self): + #Figure Return Here + self.figure, self.ax = plot(self.main_window) + # Figure Sending To Main Window With Signal + self.figureReady.emit(self.figure) + + +def plot(self): + # OHLCV Data + idf = pd.read_csv('examples/data/SPY_20110701_20120630_Bollinger.csv',index_col=0,parse_dates=True) + df = idf.loc['2011-07-01':'2011-12-30',:] + fig, axlist = mpl.plot( + df, + returnfig= True, + tight_layout= True, + figsize =(4,4), + style = 'yahoo', + type = 'candle', + scale_padding=0.25, + ) + axlist[0].xaxis.set_tick_params(labelsize=5) + axlist[0].yaxis.set_tick_params(labelsize=5) + return fig, axlist[0] \ No newline at end of file diff --git a/examples/gui_examples/Pyside 6/ui_main_window.py b/examples/gui_examples/Pyside 6/ui_main_window.py new file mode 100644 index 00000000..10c49b20 --- /dev/null +++ b/examples/gui_examples/Pyside 6/ui_main_window.py @@ -0,0 +1,70 @@ +# -*- coding: utf-8 -*- + +################################################################################ +## Form generated from reading UI file 'main_window - CopyPPBroX.ui' +## +## Created by: Qt User Interface Compiler version 6.4.3 +## +## WARNING! All changes made in this file will be lost when recompiling UI file! +################################################################################ + +from PySide6.QtCore import (QCoreApplication, QDate, QDateTime, QLocale, + QMetaObject, QObject, QPoint, QRect, + QSize, QTime, QUrl, Qt) +from PySide6.QtGui import (QBrush, QColor, QConicalGradient, QCursor, + QFont, QFontDatabase, QGradient, QIcon, + QImage, QKeySequence, QLinearGradient, QPainter, + QPalette, QPixmap, QRadialGradient, QTransform) +from PySide6.QtWidgets import (QApplication, QHBoxLayout, QLayout, QMainWindow, + QPushButton, QSizePolicy, QVBoxLayout, QWidget) + +class Ui_MainWindow(object): + def setupUi(self, MainWindow): + if not MainWindow.objectName(): + MainWindow.setObjectName(u"MainWindow") + MainWindow.setWindowModality(Qt.NonModal) + MainWindow.resize(697, 447) + sizePolicy = QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(MainWindow.sizePolicy().hasHeightForWidth()) + MainWindow.setSizePolicy(sizePolicy) + self.centralwidget = QWidget(MainWindow) + self.centralwidget.setObjectName(u"centralwidget") + self.verticalLayout = QVBoxLayout(self.centralwidget) + self.verticalLayout.setObjectName(u"verticalLayout") + self.horizontalLayout_2 = QHBoxLayout() + self.horizontalLayout_2.setObjectName(u"horizontalLayout_2") + self.horizontalLayout_2.setSizeConstraint(QLayout.SetFixedSize) + + self.verticalLayout.addLayout(self.horizontalLayout_2) + + self.horizontalLayout = QHBoxLayout() + self.horizontalLayout.setObjectName(u"horizontalLayout") + self.horizontalLayout.setSizeConstraint(QLayout.SetFixedSize) + self.plot = QPushButton(self.centralwidget) + self.plot.setObjectName(u"plot") + sizePolicy1 = QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) + sizePolicy1.setHorizontalStretch(0) + sizePolicy1.setVerticalStretch(0) + sizePolicy1.setHeightForWidth(self.plot.sizePolicy().hasHeightForWidth()) + self.plot.setSizePolicy(sizePolicy1) + self.plot.setMaximumSize(QSize(115, 24)) + + self.horizontalLayout.addWidget(self.plot) + + + self.verticalLayout.addLayout(self.horizontalLayout) + + MainWindow.setCentralWidget(self.centralwidget) + + self.retranslateUi(MainWindow) + + QMetaObject.connectSlotsByName(MainWindow) + # setupUi + + def retranslateUi(self, MainWindow): + MainWindow.setWindowTitle(QCoreApplication.translate("MainWindow", u"Market Insight", None)) + self.plot.setText(QCoreApplication.translate("MainWindow", u"plot", None)) + # retranslateUi + From 0a40a22ba34944fd15449e419e9642b594ffe1bd Mon Sep 17 00:00:00 2001 From: "Dr. Chandrakant Bangar" <127198654+DrChandrakant@users.noreply.github.com> Date: Wed, 21 Jun 2023 18:01:11 +0530 Subject: [PATCH 2/2] Example Added For Major GUI Packages Example Added For Major GUI Packages Like Pyside6 , PyQt5 and PyQt6 --- src/mplfinance/_version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mplfinance/_version.py b/src/mplfinance/_version.py index 9929be97..bc874c3c 100644 --- a/src/mplfinance/_version.py +++ b/src/mplfinance/_version.py @@ -1,4 +1,4 @@ -version_info = (0, 12, 9, 'beta', 8) +version_info = (0, 12, 9, 'beta', 9) _specifier_ = {'alpha': 'a','beta': 'b','candidate': 'rc','final': ''}