AttributeError when creating pyqtgraph plots inside the main function

1,796 views
Skip to first unread message

pytho...@gmail.com

unread,
Aug 5, 2016, 1:06:38 PM8/5/16
to pyqtgraph
Hi All,

I have recently started using Python and pyqtgraph so apologies for a rather basic question. I am trying to read some data from a file and plot it using pyqtgraph (as given in the code below). All the plot initialization is done in the main function and then the plot is updated through a QTimer. However, when I try to run this code, it returns the error:

QtGui.QApplication.instance().exec_()
AttributeError: 'NoneType' object has no attribute 'exec_'

Any help with this would be much appreciated.

Thanks.

import multiprocessing
import numpy as np
import sys
import pyqtgraph as pg
from pyqtgraph.Qt import QtCore, QtGui
import ReadData

def main():
    matrix_main
= np.memmap('myData.dat', dtype='float64', mode='w+', shape=(5000, 5))

    p
= multiprocessing.Process(target=ReadData.worker)
    p
.start()

    win1
= pg.GraphicsWindow()
    win1
.setWindowTitle('Data plot')

    p1
= win1.addPlot()

    index
= int(matrix_main[0, 0])
   
curve1 = p1.plot(matrix_main[:index, 2], pen='k')
    pg
.QtGui.QApplication.processEvents()
    timer
= pg.QtCore.QTimer()
    timer
.timeout.connect(update1)
    timer
.start(1000)

def update1():
   
global curve1, matrix_main
    index
= int(matrix_main[0, 0])
    curve1
.setData(matrix_main[:index, 2])

if __name__ == '__main__':
   
if (sys.flags.interactive != 1) or not hasattr(QtCore, 'PYQT_VERSION'):
       
QtGui.QApplication.instance().exec_()
        main
()


vas...@gmail.com

unread,
Aug 5, 2016, 3:13:53 PM8/5/16
to pyqt...@googlegroups.com
If you not plan to use classes maybe could start with:

import multiprocessing
import numpy as np
import sys
import pyqtgraph as pg
import ReadData

def main():
    global curve1, matrix_main
    # global qapp

   
    matrix_main = np.memmap('myData.dat', dtype='float64', mode='w+', shape=(5000, 5))

    p = multiprocessing.Process(target=ReadData.worker)
    p.start()

    qapp=pg.mkQApp()

    win1 = pg.GraphicsWindow()
    win1.setWindowTitle('Data plot')
    win1.show()


    p1 = win1.addPlot()

    index = int(matrix_main[0, 0])
    curve1 = p1.plot(matrix_main[:index, 2], pen='k')
    # qapp.processEvents()


    timer = pg.QtCore.QTimer()
    timer.timeout.connect(update1)
    timer.start(1000)
    sys.exit(qapp.exec_())


def update1():
    global curve1, matrix_main
    # global qapp

    index = int(matrix_main[0, 0])
    curve1.setData(matrix_main[:index, 2])
    # qapp.processEvents()

main()



P.S. I am not sure that processEvents is necessary, so I commented it out.


Good luck,
Vasilije

--
You received this message because you are subscribed to the Google Groups "pyqtgraph" group.
To unsubscribe from this group and stop receiving emails from it, send an email to pyqtgraph+unsubscribe@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/pyqtgraph/59f2c28e-34a9-4c28-8ad6-2670422932c3%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

pytho...@gmail.com

unread,
Aug 5, 2016, 4:37:48 PM8/5/16
to pyqtgraph
Hi Vasilije,

Many thanks for your solution - it works well!

I understand that qapp = pg.mkQApp() initializes the application but not too sure about the precise meaning of  sys.exit(qapp.exec_()). Also how would these commands change if I were using them within classes.

Finally, I realize that as the 'matrix_main' array size increases over time, the plot would take up more and more RAM memory. Is there anyway to improve this situation (e.g. calling garbage collection) - I guess that with 'curve1.setData', previous trace is already being deleted before new one is plotted.

Many thanks for your help.

vas...@gmail.com

unread,
Aug 5, 2016, 5:48:28 PM8/5/16
to pyqt...@googlegroups.com
qapp.exec_() runs a GUI event loop that waits for user actions (events).
In your case you can also use pg.QtGui.QApplication.instance().exec_(). Exiting from that loop can be done with qapp.exit_() or pg.QtGui.QApplication.instance().exit()

This is a simplest solution (I can found) when you want to use classes. I also commented out some rows I think you not currently need it.

import multiprocessing
import numpy as np
import sys
import pyqtgraph as pg
import ReadData

class MyClass(object):
   
    def __init__(self):
        self.matrix_main = np.memmap('myData.dat', dtype='float64', mode='w+', shape=(5000, 5))

        p = multiprocessing.Process(target=ReadData.worker)
        p.start()
        win1 = pg.GraphicsWindow()
        win1.setWindowTitle('Data plot')       
        p1 = win1.addPlot()
        # index = int(self.matrix_main[0, 0])
        self.curve1 = p1.plot()  # matrix_main[:index, 2], pen='k')
        timer = pg.QtCore.QTimer()
        timer.timeout.connect(self.update1)
        timer.start(0)   
        pg.QtGui.QApplication.instance().exec_()

    def update1(self):
        index = int(self.matrix_main[0, 0])
        self.curve1.setData(self.matrix_main[:index, 2])
        # pg.QtGui.QApplication.processEvents()
       

if __name__ == '__main__':
    mc = MyClass()
    # if (sys.flags.interactive != 1) or not hasattr(QtCore, 'PYQT_VERSION'):
        # QtGui.QApplication.instance().exec_()


P.S. You could clear your plot data if you call self.curve1.clear().

Good luck again,
Vasilije

--
You received this message because you are subscribed to the Google Groups "pyqtgraph" group.
To unsubscribe from this group and stop receiving emails from it, send an email to pyqtgraph+unsubscribe@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages