Memory leak when embedding and updating a matplotlib graph in a PyQt GUI

前端 未结 2 1704
轮回少年
轮回少年 2021-01-18 20:52

I am trying to embed a matplotlib graph that updates every second into a PyQt GUI main window.

In my program I call an update function every second using thread

相关标签:
2条回答
  • 2021-01-18 21:26

    The problem is definitely not with how you are appending to your numpy array, or truncating it.

    The problem here is with your threading model. Integrating calculation loops with a GUI control loop is difficult.

    Fundamentally, you need your GUI threading to have control of when your update code is called (spawning a new thread to handle it if necessary) - so that

    1. your code does not block the GUI updating,
    2. the GUI updating does not block your code executing and
    3. you don't spawn loads of threads holding multiple copies of objects (which might be where your memory leak comes from).

    In this case, as your main window is controlled by PyQt4, you want to use a QTimer (see a simple example here)

    So - alter your timer code to

    def task(self):
        getCH4()
        getCO2()
        getConnectedDevices()
        self.dc.update_figure()
    
    def timer(self):
        self.t = QtCore.QTimer()
        self.t.timeout.connect(self.task)
        self.t.start(1000)
    

    and this should work. Keeping the reference to the QTimer is essential - hence self.t = QtCore.QTimer() rather than t = QtCore.QTimer(), otherwise the QTimer object will be garbage collected.


    Note:

    This is a summary of a long thread in chat clarifying the issue and working through several possible solutions. In particular - the OP managed to mock up a simpler runnable example here: http://pastebin.com/RXya6Zah

    and the fixed version of the full runnable example is here: http://pastebin.com/gv7Cmapr

    The relevant code and explanation is above, but the links might help anyone who wants to replicate / solve the issue. Note that they require PyQt4 to be installed

    0 讨论(0)
  • 2021-01-18 21:30

    if you are creating a new figure for every time this is quite common.

    matplotlib do not free the figures you create, unless you ask it, somethink like:

    pylab.close() 
    

    see How can I release memory after creating matplotlib figures

    0 讨论(0)
提交回复
热议问题