2

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.

Daniel Do
  • 51
  • 7
  • 3
    Please reduce your code to the minimum required to demonstrate the problem! – Klaus D. Mar 01 '21 at 14:00
  • gpio callbacks are called in context of non-main thread. You need to pass message from that callback thread into main thread to control GUI. – Maxim Sagaydachny Mar 01 '21 at 14:30
  • I try to overlook the code and reduce it! Could you elaborate the callback problem ? - The GPIOs work fine with and without GUI also the controll of the GUI works fine aswell its just the memory problem. Thanks – Daniel Do Mar 01 '21 at 14:51

0 Answers0