Getting values from a Pyqt5 chart

564 Views Asked by At

Trying to pull values from a pyqt5 chart when hovering the mouse over a position.

The Series is a Candlestick series with values Adj_Open, Adj_High, Adj_Low, Adj_Close.

def call_sym_data(self):
    self.chartlayout.removeWidget(self.chartviewer)
    sym = self.sym_input.text()
    sym_raw = quandl.get("EOD/"+sym, start_date = sdate, end_date = edate)
    self.symlabel.setText(self.sym_input.text())
    can_data = pd.DataFrame( columns = ['Adj_Open','Adj_High','Adj_Low','Adj_Close'])
    can_data['Adj_Open'] = sym_raw['Adj_Open']
    can_data['Adj_High'] = sym_raw['Adj_High']
    can_data['Adj_Low'] = sym_raw['Adj_Low']
    can_data['Adj_Close'] = sym_raw['Adj_Close']
    
    print(can_data)
    sym_date = sym_raw.index
    
    series = QCandlestickSeries()
    series.setDecreasingColor(Qt.red)
    series.setIncreasingColor(Qt.green)
    
    
    for  index, row in can_data.iterrows():
        series.append(QCandlestickSet(row['Adj_Open'], row['Adj_High'], row['Adj_Low'], row['Adj_Close']))
        
       
    
    self.sym_chart = QChart()
    
    self.sym_chart.addSeries(series)
    
    self.sym_chart.setAnimationOptions(QChart.SeriesAnimations)
    self.sym_chart.createDefaultAxes()
    self.sym_chart.legend().hide()
    
    self.sym_chart.axisX(series).setCategories(sym_date.strftime("%Y-%m-%d"))
    
    
    self.chartviewer = QChartView(self.sym_chart)
    self.chartlayout.addWidget(self.chartviewer)

The objective is to hover the mouse over the specific bar and have it change the label of Open, High, Low, and Close on the output in the picture. The labels are bar_open, bar_high, bar_low, and bar_close.

Symbol Chart

I can't figure out how to get hovered to work and show each value, and mapToPosition doesn't seem to help.

2

There are 2 best solutions below

0
On

There is a QCandlestickSeries signal available - hovered. This returns the underlying QCandlestickSet upon emission due to hovering over the corresponding Candlestick Set.

A slot can be added and connected to this signal. In the slot, the data from the QCandlestickSet can be extracted and used to update the labels.

Though there is one problem - the addition of pyqtSlot decorator for the slot. It errors out with following signal

QObject::connect: Incompatible sender/receiver arguments  QtCharts::QCandlestickSeries::doubleClicked(QCandlestickSet*)
0
On

This works in Qt6|Qt5...
The example was made using PySide6|PySide2, but something similar should work for PyQt.
(Just make sure to attach an event-handler to every single data-point, instead of to the whole series.)

# Event-handler:
def mouseHoverCandle (self):
    sender = self.sender()
    if sender:  
        myui.labelTest.setText(f"O: {sender.open()}, H: {sender.high()}, L: {sender.low()}, C: {sender.close()}")


# To attach the event-handler, use...:
series = QtCharts.QCandlestickSeries()
#...
for candle in series.sets():                   
    candle.hovered.connect(self.mouseHoverCandle)