HRarnob07
HRarnob07

Reputation: 161

Graph scrolling using pyqt5 and malplotlib

previous question (link)

Here i want that when i move the scroll bar using mouse it will not scroll the graph but when i leave the mouse then the graph will be updated. Here every time axis limit are updating but i want it will update the axis limit when i leave the mouse moving the scroll bar at a certain position.
Note : Here y -axis trick label position will be fixed and it would be visible but value will update when i scroll the graph.and i also want that scroll bar will start from right position.

Here my program :

import sys
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
import matplotlib.pyplot as plt
from matplotlib.figure import Figure
from PyQt5.QtWidgets import QMainWindow,QVBoxLayout
from PyQt5.QtWidgets import QApplication
from PyQt5 import QtCore, QtGui, QtWidgets
import datetime
from matplotlib.dates import num2date, date2num
from mpl_finance import candlestick_ochl as candlestick
import numpy as np
import matplotlib.ticker as ticker
import matplotlib.dates as mdates
import pylab as pl
class MainWindow_code_serarch(object):

    def setup_code_serarch(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(1070, 680)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.verticalLayoutWidget1 = QtWidgets.QWidget(self.centralwidget)
        self.verticalLayoutWidget1.setGeometry(QtCore.QRect(17, 30, 741, 13))
        self.verticalLayoutWidget1.setObjectName("verticalLayoutWidget")
        self.verticalLayout1 = QtWidgets.QVBoxLayout(self.verticalLayoutWidget1)
        self.verticalLayout1.setContentsMargins(0, 0, 0, 0)
        self.verticalLayout1.setObjectName("verticalLayout1")
        self.verticalLayoutWidget = QtWidgets.QWidget(self.centralwidget)
        self.verticalLayoutWidget.setGeometry(QtCore.QRect(17, 10, 1040, 603))
        self.verticalLayoutWidget.setObjectName("verticalLayoutWidget")
        self.verticalLayout = QtWidgets.QVBoxLayout(self.verticalLayoutWidget)
        self.verticalLayout.setContentsMargins(0, 0, 0, 0)
        self.verticalLayout.setObjectName("verticalLayout")
        self.figure = Figure(figsize=(100,7.2), dpi=80, facecolor='k')
        self.canvas = FigureCanvas(self.figure)
        self.canvas.draw()
        # self.widget = QtWidgets.QWidget()
        # self.scroll_area = QtWidgets.QScrollArea(self.widget)
        # self.scroll_area.setWidget(self.canvas)
        # self.verticalLayout.addWidget(self.scroll_area)
        self.scroll = QtWidgets.QScrollBar(QtCore.Qt.Horizontal)
        self.axes, self.axes2 = self.figure.subplots(nrows=2, sharex=True)


        self.verticalLayout.addWidget(self.canvas)
        self.verticalLayout.addWidget(self.scroll)


        data = {
            'date': ['2018/10/29','2018/10/30', '2018/11/03', '2018/11/04', '2018/11/05', '2018/11/07', '2018/11/10', '2018/11/11','2018/11/12','2018/11/13'],
            'open': [8824,8824, 8726.31, 8642.14, 8531.51, 8630.25, 8602.50, 8640.22,8202.50, 8610.22],
            'high': [8858,8858, 8748.60, 8551.36, 8653.16, 8476.69, 8630, 8570.56 ,8602.50, 8640.22],
            'low': [8688,8688, 8743.67, 8550.76, 8449.50, 8631.83, 8602.18, 8743.22 ,8502.50, 8540.22],
            'close': [8820,8820, 8747.17, 8550.52, 8553., 8517.10, 8628.78, 8588.52 ,8602.50, 8640.22],
            'volume': [17759.56,17759.56, 120000.17, 18739.52, 38599.50, 16517.10, 17723.78, 15588.52 ,28602.50, 28640.22]
        }
        x = date2num([datetime.datetime.strptime(d, '%Y/%m/%d').date() for d in data['date']])
        t= np.arange(len(data['date']))
        candle_trace = zip(t, data['open'], data['high'], data['low'], data['close'], data['volume'])
        candlestick(self.axes, candle_trace, width=.75, colorup='g', colordown='r')
        self.axes2.plot(t, [1, 2, 3, 4, 7, 8, 9,6,6,9])
        self.axes.set_position([0.02, 0.37, 0.88, 0.6])
        self.axes2.set_position([0.02, 0.15, 0.88, 0.22])
        self.axes.tick_params(axis='both', color='#ffffff', labelcolor='#ffffff')
        self.axes.yaxis.tick_right()
        self.axes2.tick_params(axis='both', color='#ffffff', labelcolor='#ffffff')
        self.axes2.grid(color='lightgray', linewidth=.5, linestyle=':')
        self.axes.grid(color='lightgray', linewidth=.5, linestyle=':')
        self.axes2.yaxis.tick_right()
        self.axes.autoscale_view()
        self.axes2.autoscale_view()
        self.axes.set_facecolor('#041105')
        self.axes2.set_facecolor('#041105')
        # N = len(dates)
        self.axes.set_xticks(range(0, len((x)), 1))
        self.axes.set_xticklabels([mdates.num2date(d).strftime('%b-%d') for d in x])
        self.axes.set_xticklabels([mdates.num2date(d).strftime('%Y-%m-%d') for d in x])
        self.axes2.set_xticklabels([mdates.num2date(d).strftime('%Y-%m-%d') for d in x])
        self.canvas.draw()
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 246, 21))
        self.menubar.setObjectName("menubar")
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)
        # self.pushButton.clicked.connect(self.graphShowCode)
        self.step = .1
        self.setupSlider()

        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", "OK"))

    def setupSlider(self):
        self.lims = np.array(self.axes2.get_xlim())
        print("limit"+str(self.lims))
        self.scroll.setPageStep(self.step * 100)
        self.scroll.actionTriggered.connect(self.update)
        self.update()

    def update(self, evt=None):
        r = self.scroll.value() / ((1 + self.step) * 100)
        l1 = self.lims[0] + r * np.diff(self.lims)
        l2 = l1 + np.diff(self.lims) * self.step
        self.axes2.set_xlim(l1, l2)
        self.axes.set_xlim(l1, l2)
        print(self.scroll.value(), l1, l2)
        self.figure.canvas.draw_idle()
if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    MainWindow = QtWidgets.QMainWindow()
    ui = MainWindow_code_serarch()
    ui.setup_code_serarch(MainWindow)
    MainWindow.show()
    sys.exit(app.exec_())

output

Upvotes: 1

Views: 1687

Answers (1)

HRarnob07
HRarnob07

Reputation: 161

QScrollBar inherits a comprehensive set of signals from QAbstractSlider. I have used sliderReleased(). because it is emit when the user releases the slider.
To start scroll bar from right position. I initiate scroll bar value (99) Because here i find scroll bar minimal value is (0) and maximum value is (99).

my program :

import sys
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
import matplotlib.pyplot as plt
from matplotlib.figure import Figure
from PyQt5.QtWidgets import QMainWindow,QVBoxLayout
from PyQt5.QtWidgets import QApplication
from PyQt5 import QtCore, QtGui, QtWidgets
import datetime
from matplotlib.dates import num2date, date2num
from mpl_finance import candlestick_ochl as candlestick
import numpy as np
import matplotlib.ticker as ticker
import matplotlib.dates as mdates
import pylab as pl
class MainWindow_code_serarch(object):

    def setup_code_serarch(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(1070, 680)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.verticalLayoutWidget1 = QtWidgets.QWidget(self.centralwidget)
        self.verticalLayoutWidget1.setGeometry(QtCore.QRect(17, 30, 741, 13))
        self.verticalLayoutWidget1.setObjectName("verticalLayoutWidget")
        self.verticalLayout1 = QtWidgets.QVBoxLayout(self.verticalLayoutWidget1)
        self.verticalLayout1.setContentsMargins(0, 0, 0, 0)
        self.verticalLayout1.setObjectName("verticalLayout1")
        self.verticalLayoutWidget = QtWidgets.QWidget(self.centralwidget)
        self.verticalLayoutWidget.setGeometry(QtCore.QRect(17, 10, 1040, 603))
        self.verticalLayoutWidget.setObjectName("verticalLayoutWidget")
        self.verticalLayout = QtWidgets.QVBoxLayout(self.verticalLayoutWidget)
        self.verticalLayout.setContentsMargins(0, 0, 0, 0)
        self.verticalLayout.setObjectName("verticalLayout")
        self.figure = Figure(figsize=(100,7.2), dpi=80, facecolor='k')
        self.canvas = FigureCanvas(self.figure)
        self.canvas.draw()
        # self.widget = QtWidgets.QWidget()
        # self.scroll_area = QtWidgets.QScrollArea(self.widget)
        # self.scroll_area.setWidget(self.canvas)
        # self.verticalLayout.addWidget(self.scroll_area)
        self.scroll = QtWidgets.QScrollBar(QtCore.Qt.Horizontal)
        self.axes, self.axes2 = self.figure.subplots(nrows=2, sharex=True)


        self.verticalLayout.addWidget(self.canvas)
        self.verticalLayout.addWidget(self.scroll)
        self.scroll.setValue(99)


        data = {
            'date': ['2018/10/29','2018/10/30', '2018/11/03', '2018/11/04', '2018/11/05', '2018/11/07', '2018/11/10', '2018/11/11','2018/11/12','2018/11/13'],
            'open': [8824,8824, 8726.31, 8642.14, 8531.51, 8630.25, 8602.50, 8640.22,8202.50, 8610.22],
            'high': [8858,8858, 8748.60, 8551.36, 8653.16, 8476.69, 8630, 8570.56 ,8602.50, 8640.22],
            'low': [8688,8688, 8743.67, 8550.76, 8449.50, 8631.83, 8602.18, 8743.22 ,8502.50, 8540.22],
            'close': [8820,8820, 8747.17, 8550.52, 8553., 8517.10, 8628.78, 8588.52 ,8602.50, 8640.22],
            'volume': [17759.56,17759.56, 120000.17, 18739.52, 38599.50, 16517.10, 17723.78, 15588.52 ,28602.50, 28640.22]
        }
        x = date2num([datetime.datetime.strptime(d, '%Y/%m/%d').date() for d in data['date']])
        t= np.arange(len(data['date']))
        candle_trace = zip(t, data['open'], data['high'], data['low'], data['close'], data['volume'])
        candlestick(self.axes, candle_trace, width=.75, colorup='g', colordown='r')
        self.axes2.plot(t, [1, 2, 3, 4, 7, 8, 9,6,6,9])
        self.axes.set_position([0.02, 0.37, 0.88, 0.6])
        self.axes2.set_position([0.02, 0.15, 0.88, 0.22])
        self.axes.tick_params(axis='both', color='#ffffff', labelcolor='#ffffff')
        self.axes.yaxis.tick_right()
        self.axes2.tick_params(axis='both', color='#ffffff', labelcolor='#ffffff')
        self.axes2.grid(color='lightgray', linewidth=.5, linestyle=':')
        self.axes.grid(color='lightgray', linewidth=.5, linestyle=':')
        self.axes2.yaxis.tick_right()
        self.axes.autoscale_view()
        self.axes2.autoscale_view()
        self.axes.set_facecolor('#041105')
        self.axes2.set_facecolor('#041105')
        # N = len(dates)
        self.axes.set_xticks(range(0, len((x)), 1))
        self.axes.set_xticklabels([mdates.num2date(d).strftime('%b-%d') for d in x])
        self.axes.set_xticklabels([mdates.num2date(d).strftime('%Y-%m-%d') for d in x])
        self.axes2.set_xticklabels([mdates.num2date(d).strftime('%Y-%m-%d') for d in x])
        self.canvas.draw()
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 246, 21))
        self.menubar.setObjectName("menubar")
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)
        # self.pushButton.clicked.connect(self.graphShowCode)
        self.step = .1
        self.setupSlider()

        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", "OK"))

    def setupSlider(self):
        self.lims = np.array(self.axes2.get_xlim())
        print("limit"+str(self.lims))
        self.scroll.setPageStep(self.step * 100)
        # self.scroll.actionTriggered.connect(self.update)
        self.scroll.sliderReleased.connect(self.update)

        self.update()

    def update(self, evt=None):
        r = self.scroll.value() / ((1 + self.step) * 100)
        l1 = self.lims[0] + r * np.diff(self.lims)
        l2 = l1 + np.diff(self.lims) * self.step
        self.axes2.set_xlim(l1, l2)
        self.axes.set_xlim(l1, l2)
        print(self.scroll.value(), l1, l2)
        self.figure.canvas.draw_idle()
if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    MainWindow = QtWidgets.QMainWindow()
    ui = MainWindow_code_serarch()
    ui.setup_code_serarch(MainWindow)
    MainWindow.show()
    sys.exit(app.exec_())

output

Upvotes: 2

Related Questions