Using __call__ method with pyqtgraph to update plot widget help setData not working

Viewed 27

Hi I'm struggling with some code here. What I have are two widgets in a window. Widget 1 is a timer which can take an input and Widget 2 is a graph. What I want to do is to collect data at an interval specified by the timer. Both of the widgets are in a different widget or class called window. The problem I have is that when I setData for the graph widget the graph doesn't seem to update. The call is called by the timer widget when it's count is 0. self.readpanda() then uploads some data and calls the updatePlot() function. I can see that the plotData array gets bigger but the graph doesn't update. See code for graph widget:


## importing libraries
from dataclasses import dataclass
from PyQt5.QtWidgets import *
from PyQt5 import QtCore, QtGui
from PyQt5.QtGui import *
from PyQt5.QtCore import *
from pyqtgraph import PlotWidget, plot
import pyqtgraph as pg
import sys
import numpy as np
import pandas as pd
import csv
from alicat import FlowController, FlowMeter
import time
import datetime
import sys
import os




# global variables
global count
global data
data = []
count = 30


# Timestamp function   
def timestamp():
    return int(time.mktime(datetime.datetime.now().timetuple()))

#TimeAxis Function
class TimeAxisItem(pg.AxisItem):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.setLabel(text='Time', units=None)
        self.enableAutoSIPrefix(False)

    def tickStrings(self, values, scale, spacing):
        return [datetime.datetime.fromtimestamp(value).strftime("%H:%M:%S") for value in values]


class Graph(QWidget):
  
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.plot = pg.PlotWidget(
            title="GC Composition",
            labels={'left': 'Gas Composition  %'},
            axisItems={'bottom': TimeAxisItem(orientation= 'bottom')}
        )
        
        self.plot.setYRange(0, 100)
        self.plot.enableAutoRange(axis='x',enable=True)
        # self.plot.setXRange(timestamp(), timestamp() + 100)
        self.plot.showGrid(x=True, y=True)

        self.layout = QVBoxLayout()
        self.setLayout(self.layout)
        self.layout.addWidget(self.plot)

        self.plotCurve1 = self.plot.plot(pen='y')
        self.plotCurve2 = self.plot.plot(pen='r')
        self.plotCurve3 = self.plot.plot(pen='g')

        self.plotData = {'t': [], 'H2': [], 'O2':[],'CO2':[]}
        
        # self.timer = QtCore.QTimer()
        # self.timer.setInterval(1000*count)
        # self.timer.timeout.connect(self.readpanda)
        # self.timer.start()

    def __call__(self, *args, **kwargs):
        if count==0:
            self.readpanda()
        
    def updatePlot(self, newValues):
        
        self.plotData['H2'].append(newValues[1])
        self.plotData['O2'].append(newValues[2])
        self.plotData['CO2'].append(newValues[3])
        self.plotData['t'].append(newValues[0])

        print(self.plotData)

        self.plotCurve1.setData(self.plotData['t'],self.plotData['H2'])
        self.plotCurve2.setData(self.plotData['t'],self.plotData['O2'])
        self.plotCurve3.setData(self.plotData['t'],self.plotData['CO2'])
        

    def readpanda(self):
        # Initialize rows list
        rows=[]
        #read csv file
        with open('CH1.LOG') as f:
            # creating a reader object (issue with header)
            file = csv.reader(f,delimiter='\t')
            # file = pd.read_csv(f, delimiter= '\t', header=None)

            # extract each data row by row
            for line in file:
                pass
            rows = line
            
            # with new list rows loop through each row to index through categories H2, O2, CO2 and extract data for timestamp, and category peak area
            datarow=[]
            datarow.append(timestamp())
            # int(time.mktime(datetime.datetime.now().timetuple())))
            iH2 = rows.index("H2")
            datarow.append(eval(rows[iH2+2]))
            # fields.append(H2)
            iO2 = rows.index("O2")
            datarow.append(eval(rows[iO2+2]))
            # print(O2)
            iCO2 = rows.index("CO2")
            datarow.append(eval(rows[iCO2+2]))
            # print(datarow)
            global data
            # print(datarow)
            data.append(datarow)

        
        self.updatePlot(datarow)
        
        global count
        count = 30

          
# Timer Widget

class MyWidget(QWidget):

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        
        self.layout = QVBoxLayout()
        self.layout.setSpacing(10)
        self.layout.setContentsMargins(10,10,10,10)
        self.setLayout(self.layout)

        # calling method
        self.UiComponents()

        # creating an instance of Graph so that it can be called again
        self.Graph=Graph()
        # showing all the widgets
        self.show()
        

    # method for widgets
    def UiComponents(self):

        # variables
        # count variable
        global count 
        count = 30

        # start flag
        self.start = False

        # creating push button to get time in seconds
        button = QPushButton("Set time(s)", self)

        # setting geometry to the push button
        self.layout.addWidget(button)

        # adding action to the button
        button.clicked.connect(self.get_seconds)

        # creating label to show the seconds
        self.label = QLabel("//TIMER//", self)

        # setting geometry of label
        self.layout.addWidget(self.label)

        # setting border to the label
        self.label.setStyleSheet("border : 3px solid black")

        # setting font to the label
        self.label.setFont(QFont('Times', 15))

        # setting alignment ot the label
        self.label.setAlignment(Qt.AlignCenter)

        # resize label
        self.label.resize(1,1)

        # creating start button
        start_button = QPushButton("Start", self)

        # setting geometry to the button
        self.layout.addWidget(start_button)

        # adding action to the button
        start_button.clicked.connect(self.start_action)

        # creating pause button
        pause_button = QPushButton("Pause", self)

        # setting geometry to the button
        self.layout.addWidget(pause_button)

        # adding action to the button
        pause_button.clicked.connect(self.pause_action)

        # creating reset button
        reset_button = QPushButton("Reset", self)

        # setting geometry to the button
        self.layout.addWidget(reset_button)

        # adding action to the button
        reset_button.clicked.connect(self.reset_action)

        # creating a timer object
        timer = QTimer(self)

        # adding action to timer
        timer.timeout.connect(self.showTime)

        # update the timer every tenth second
        timer.start(100)
        

    # method called by timer
    def showTime(self):

        # checking if flag is true
        if self.start:
            # incrementing the counter
            global count 
            count -= 1

        # timer is completed
        if count == 0:

            # making flag false
            self.start = False

            # setting text to the label
            self.label.setText("Completed !!!! ")  
           
            # calling Graph class call function to read file and update chart
            self.Graph()

        if self.start:
            # getting text from count
            text = str(count / 10) + " s"

            # showing text
            self.label.setText(text)


    # method called by the push button
    def get_seconds(self):
        global count
        # making flag false
        self.start = False

        # getting seconds and flag
        second, done = QInputDialog.getInt(self, 'Seconds', 'Enter Seconds:')

        # if flag is true
        if done:
            # changing the value of count
            count = second * 10

            # setting text to the label
            self.label.setText(str(second))

    def start_action(self):
        global count
        # making flag true
        self.start = True

        # count = 0
        if count == 0:
            self.start = False

    def pause_action(self):

        # making flag false
      self.start = False

    def reset_action(self):
        global count
        # making flag false
        self.start = False

        # setting count value to 0
        count = 0

        # setting label text
        self.label.setText("//TIMER//")

class Window(QMainWindow):

    def __init__(self):
        super().__init__()
        self.init_gui()
        # setting title
        self.setWindowTitle("Python ")

        # setting geometry
        self.setGeometry(100, 100, 400, 600)

    def init_gui(self):
        self.window = QWidget()
        self.layout = QGridLayout()
        self.setCentralWidget(self.window)
        self.window.setLayout(self.layout)

        self.Mywidget= MyWidget()
        self.Graph = Graph()


        self.layout.addWidget(self.Mywidget,0,0,1,1)
        self.layout.addWidget(self.Graph,1,1,50,50)
        
        



def main():
    # create pyqt5 app
    App = QApplication(sys.argv)
  
    # create the instance of our Window
    window = Window()
    window.show()

    
    
    # start the app
    sys.exit(App.exec())

    


if __name__ == '__main__':
   main()
0 Answers
Related