finplot candlestick chart does not render on launch when rendered as a widget

Viewed 308

I have placed finplot candlestick chart as a widget. When launched, it comes up black on first render of app. If I zoom out, it starts to show up in the maximum zoomed state. How can I launch it in a state so that all candles that are inside the chart is displayed. Following is my entire code.

import sys

import finplot as fplt
import pandas as pd
import pyqtgraph as pg
import requests
from PyQt5.QtWidgets import *


# Creating the main window
class App(QMainWindow):
    def __init__(self):
        super().__init__()
        self.title = 'PyQt5 - QTabWidget'
        self.left = 0
        self.top = 0
        self.width = 1200
        self.height = 800
        self.setWindowTitle(self.title)
        self.setGeometry(self.left, self.top, self.width, self.height)

        self.tab_widget = MyTabWidget(self)
        self.setCentralWidget(self.tab_widget)

        self.show()

    # Creating tab widgets


class MyTabWidget(QWidget):
    def __init__(self, parent):
        super(QWidget, self).__init__(parent)
        self.layout = QVBoxLayout(self)

        # Initialize tab screen
        self.tabs = QTabWidget()
        self.tabs.setTabPosition(QTabWidget.East)
        self.tabs.setMovable(True)

        self.tab1 = QWidget()

        self.tabs.resize(600, 400)

        # Add tabs
        self.tabs.addTab(self.tab1, "tab1")


        self.tab1.layout = QVBoxLayout(self)
        self.tab1.label = QLabel("USDT-BTC")
        
        self.tab1.fplt_widget = pg.PlotWidget(plotItem=fplt.create_plot_widget(self.window()))

        self.tab1.btn = QPushButton("Press me")

        # pull some data
        symbol = 'USDT-BTC'
        url = 'https://bittrex.com/Api/v2.0/pub/market/GetTicks?marketName=%s&tickInterval=fiveMin' % symbol
        data = requests.get(url).json()

        # format it in pandas
        df = pd.DataFrame(data['result'])
        df = df.rename(columns={'T':'time', 'O':'open', 'C':'close', 'H':'high', 'L':'low', 'V':'volume'})
        df = df.astype({'time':'datetime64[ns]'})
        candles = df[['time','open','close','high','low']]


        fplt.candlestick_ochl(candles)

        self.tab1.layout.addWidget(self.tab1.label)
        self.tab1.layout.addWidget(self.tab1.fplt_widget)
        self.tab1.layout.addWidget(self.tab1.btn)
        self.tab1.setLayout(self.tab1.layout)

        # Add tabs to widget
        self.layout.addWidget(self.tabs)
        self.setLayout(self.layout)


if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = App()
    sys.exit(app.exec_())

Here is my app when launched:

enter image description here

Here it is when one scroll zoomed out

enter image description here

I want to see it as follows as soon as it launches

enter image description here

1 Answers

Thank you for posting full details of your problem.

Everything is almost there. You just need to add two things:

  1. In your App.__init add one of the following lines just before calling self.show():
fplt.show(qt_exec=False)

or just

fplt.refresh()

Either choice will work because fplt.refresh() is called in either case. This autozooms your data plot, among other good things.

  1. For the refresh call to work in either of the above choices, the window instance that you passed to fplt.create_plot_widget needs an axs attribute containing a list of your fplt widgets that you created. In your case, you wrap your fplt widget in a pg.PlotWidget, so the required widget reference becomes self.tab1.fplt_widget.plotItem (note the .plotItem there). Long story short: in MyTabWidget.__init__ insert this line before adding your widget to self.tab1.layout:
self.window().axs = [self.tab1.fplt_widget.plotItem]

Running your posted code with the above changes gives me the initial plot view that you desire.

Related