Python3 - Matplotlib FuncAnimation continuous memoryleak

Viewed 101

EDIT2:

So after some more work I created the smallest sample which reproduces the Memoryleak pretty decent on every machine. This code just creates a TKinter Window and a matplotlib canvas with 3 Sine waves, than tries to animate then. See that blit is true, so it shoudnt do anything because the drawing does not change.

I also tried following ways from this post How can I release memory after creating matplotlib figures

gc.collect() - did nothing

axes.clear - it did stop endless memory to be leaked but also completely screws the picture

figure.clf - same as clear but worse.

Any other idea why FuncAnimation increases in memory usage over time????? Thanks

import tkinter as tk
from threading import Thread
from numpy import sin, cos, pi


#--Mainwindow--
class Drehstromdemonstrator(tk.Tk):

    def __init__(self):
        #Predefine

        tk.Tk.__init__(self)
        tk.Tk.wm_title(self, "Minimal")
        
        container = tk.Frame(self)
        container.pack(side="top", fill="both", expand=True)
        container.grid_rowconfigure(0, weight=1)
        container.grid_columnconfigure(0, weight=1)  

        self.frame = plotSine(self,(tk.Tk.winfo_screenwidth(self)*0.7,tk.Tk.winfo_screenheight(self)*0.7))


      
import numpy,matplotlib
matplotlib.use('TkAgg')
from numpy import sin, cos, pi, deg2rad, linspace, arange
import matplotlib.pyplot as plt
import matplotlib.animation as animation
import matplotlib.ticker as tck
import time
import math


from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
from matplotlib.figure import Figure
from math import ceil

global U1ausg, U2ausg, U3ausg, Counter_1, Counter_2, Counter_3

U1ausg = U2ausg = U3ausg = Counter_3 = 50
Counter_1 = 120
Counter_2 = 240


class plotSine:

    def __init__(self,masterframe,size):
        self._running = True

        global U1ausg
        global U2ausg
        global U3ausg

        (w,h) = size
        inchsize = (w/25.5, h/25.4)
        fig = self.figure = Figure(inchsize)

        self.axes = fig.add_subplot(111)

        self.axes.xaxis.set_ticks(arange(0,390,30))
        self.axes.margins(x=0)
        self.axes.yaxis.set_ticks(arange(-120,130,20))
        self.axes.set_ylim(-120,120)

        #create canvas as matplotlib drawing area
        self.canvas = FigureCanvasTkAgg(fig, master=masterframe)
        self.canvas.get_tk_widget().pack()
        self.x = linspace(0,360,1000)
        self.axes.grid()


        #self.drawStuff()

    #Draw the plot
    def drawStuff(self,*args):       
        ax = self.axes
       

        self.axes.legend(["U1","U2","U3"])

        #Changed everything to degree instead of PI, better looking
        ysin = int(ceil(U1ausg))*sin(50/Counter_3 * deg2rad(self.x))
        ysin2 = int(ceil(U2ausg))*sin(50/Counter_3 * deg2rad(self.x) + deg2rad(Counter_1))
        ysin3 = int(ceil(U3ausg))*sin(50/Counter_3 * deg2rad(self.x) + deg2rad(Counter_2))

        lineU1 = ax.plot(self.x, ysin, "-r",label="U1")
        lineU2 = ax.plot(self.x, ysin2, "-g",label="U2")
        lineU3 = ax.plot(self.x, ysin3, "-b",label="U3")

        

        return [*lineU1,*lineU2,*lineU3]

    #Animation to redraw when value changed
    def animate(self):
        self.ani = animation.FuncAnimation(self.figure, self.drawStuff, interval=10, blit=True)


#--Run Mainprog

try:
    app = Drehstromdemonstrator()
    plt.show()
    app.frame.animate()
    app.mainloop
# Aufraeumarbeiten nachdem das Programm beendet wurde
except UnicodeDecodeError:
    print("Interrupt aswell!")
    lampensteuerung.terminate()

except KeyboardInterrupt:
    print("Interrupt")
    lampensteuerung.terminate()

except Exception as e:
    print(e)        

EDIT1:

By try-and-error I could figure out that the problem seems to be in my matplotlib, as if I disable it the memory increase stops.


So my task is to finish this project from someone else - it simulates a 3-phased system via a raspberry and some lights. When I disable the GUI the code works splendid, no problems, fast reaction. Sometimes the PI says he has low voltage but I just think that is some weird bug because the sourcepower is really enough to power it.

Full Code removed because not needed.

0 Answers
Related