首页 > 解决方案 > Python3 - Matplotlib FuncAnimation 连续内存泄漏

问题描述

编辑2:

因此,经过更多的工作,我创建了最小的样本,它在每台机器上都可以很好地再现 Memoryleak。这段代码只是创建了一个 TKinter 窗口和一个带有 3 个正弦波的 matplotlib 画布,然后尝试制作动画。看到 blit 是真的,所以它不应该做任何事情,因为绘图不会改变。

我还尝试了这篇文章中的方法 如何在创建 matplotlib 图形后释放内存

gc.collect() - 什么也没做

axes.clear - 它确实阻止了无尽的内存泄漏,但也完全破坏了图片

figure.clf - 与 clear 相同但更糟。

任何其他想法为什么 FuncAnimation 会随着时间的推移增加内存使用量??????谢谢

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)        

编辑1:

通过反复试验,我可以发现问题似乎出在我的 matplotlib 中,就好像我禁用它一样,内存增加停止了。


所以我的任务是从其他人那里完成这个项目——它通过树莓和一些灯光模拟一个三阶段系统。当我禁用 GUI 时,代码运行良好,没有问题,反应迅速。有时 PI 说他电压低,但我只是认为这是一个奇怪的错误,因为 sourcepower 真的足以为其供电。

删除完整代码,因为不需要。

标签: pythontkintermemory-managementraspberry-pi

解决方案


推荐阅读