pythonpyqtcandlestick-chart

Are fast candlestick charts possible in Python


I tried drawing a few thousand candles in matplotlib. When scrolling the chart slows down(hangs).

Eyllanesc helped me to realize the candlestick graph in pyqt. The graph is beautiful and works faster than matplotlib.

But, all the same the chart slows down when scrolling. I changed the code a little. The file data is available here.

Are relatively fast candlestick charts possible in Python, with a large amount of data?

The fact that I have a project in C# in it tens of thousands of candles and scrolled it much faster.

The data for drawing me offline. And I really need a lot of candles. Maybe there's a function to make the graph more quickly? (I'm not criticizing anyone, I just want to sort this out.)

Here's how the C# chart works, with over 40,000 candles. I attach GIF animation.

C#

Python

from PyQt5 import QtCore, QtGui, QtWidgets, QtChart
import math
import numpy as np
import pandas as pd

df = pd.read_csv('file.txt',
                         index_col='DATE',
                         parse_dates=True,
                         infer_datetime_format=True)


o = df.iloc[:, 0].values
h = df.iloc[:, 1].values
l = df.iloc[:, 2].values
z = df.iloc[:, 3].values

class MainWindow(QtWidgets.QMainWindow):
    def __init__(self, parent=None):
        super().__init__(parent)

        self.step = 0.1
        self._chart_view = QtChart.QChartView()
        self.scrollbar = QtWidgets.QScrollBar(
            QtCore.Qt.Horizontal,
            sliderMoved=self.onAxisSliderMoved,
            pageStep=self.step * 100,
        )
        self.slider = QtWidgets.QSlider(
            QtCore.Qt.Horizontal, sliderMoved=self.onZoomSliderMoved
        )

        central_widget = QtWidgets.QWidget()
        self.setCentralWidget(central_widget)

        lay = QtWidgets.QVBoxLayout(central_widget)
        for w in (self._chart_view, self.scrollbar, self.slider):
            lay.addWidget(w)

        self.resize(640, 480)

        self._chart = QtChart.QChart()

        self._candlestick_serie = QtChart.QCandlestickSeries()


        tm = []

        for i in range(0, len(z)):
            o_ = o[i]
            h_ = h[i]
            l_ = l[i]
            c_ = z[i]
            self._candlestick_serie.append(QtChart.QCandlestickSet(o_, h_, l_, c_))
            tm.append(str(i))
        min_x, max_x = 0, i

        self._chart.addSeries(self._candlestick_serie)
        self._chart.createDefaultAxes()
        self._chart.legend().hide()
        # self._chart.setAnimationOptions(QtChart.QChart.SeriesAnimations)

        self._chart.axisX(self._candlestick_serie).setCategories(tm)
        self._chart.axisX(self._candlestick_serie).setVisible(False)

        self._chart_view.setChart(self._chart)
        self.adjust_axes(100, 200)
        self.lims = np.array([min_x, max_x])

        self.onAxisSliderMoved(self.scrollbar.value())

    def adjust_axes(self, value_min, value_max):
        self._chart.axisX(self._candlestick_serie).setRange(
            str(value_min), str(value_max)
        )

        if value_min > 0 and value_max > 0 and value_max < 10000:
            ymin = np.amin(l[int(value_min): int(value_max)])
            ymax = np.amax(h[int(value_min): int(value_max)])
            self._chart.axisY(self._candlestick_serie).setRange(ymin, ymax)

    @QtCore.pyqtSlot(int)
    def onAxisSliderMoved(self, value):
        r = value / ((1 + self.step) * 100)
        l1 = self.lims[0] + r * np.diff(self.lims)
        l2 = l1 + np.diff(self.lims) * self.step
        self.adjust_axes(math.floor(l1), math.ceil(l2))

    @QtCore.pyqtSlot(int)
    def onZoomSliderMoved(self, value):
        self.step=value/100
        self.onAxisSliderMoved(self.scrollbar.value())
        print(value)

if __name__ == "__main__":
    import sys

    app = QtWidgets.QApplication(sys.argv)
    w = MainWindow()
    w.show()
    sys.exit(app.exec_())

Solution

  • You can try pyecharts. This is based on the fantastic echarts library which uses web technology for rendering. I consider the performance of this library to be state-of-the-art in open-source charting solutions. Also it is well documented and pretty easy to work with. An interactive linechart with a million points renders smoothly on a current laptop. Did not test candlesticks, though.