How to solve the error :Figures created through the pyplot interface are retained until explicitly closed and may consume too much memory

Viewed 30

I create some windows form to (update and) view the graph when I change the values by using tk.Scale widget. I need to update the graph without any effecting to the figure.

I know we can use matplotlib.widget as :- from matplotlib.widget import scale - But I don't want to use the widget, but I want to do this by using tkinter scale widget. Because of I need to place the widget my prefer place. not to related place of the figure ! So then I tried to do this as follows (My coding parts below) But I face to some problem with the figure. The error massege is :

C:\Users\Pramudith Rangana\Desktop\New folder\grph_8.py:118: RuntimeWarning: More than 20 figures have been opened. Figures created through the pyplot interface (matplotlib.pyplot.figure) are retained until explicitly closed and may consume too much memory. (To control this warning, see the rcParam figure.max_open_warning). figure = plt.figure(figsize = (5,4), dpi = 120)

My coding patrs are here:

import numpy as np
from tkinter import *
import tkinter as tk
from tkinter import ttk
import matplotlib.pyplot as plt
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg


def main():
    my_w = Tk()
    gui = Window(my_w)
    gui.my_w.mainloop()
    return None

class Window:
    
    def __init__(self, my_w):        
        self.my_w = my_w
        self.my_w.geometry('1700x820+50+50')
        self.my_w.title('data view on tk graph')

        self.val_a = StringVar()
        self.val_b = StringVar()
        self.val_c = StringVar()

        self.num_a = 0
        self.num_b = 0
        self.num_c = 0

        wrapper1 = tk.LabelFrame(self.my_w)
        wrapper2 = tk.LabelFrame(wrapper1)
        self.wrapper3 = tk.LabelFrame(wrapper1)
        wrapper4 = tk.LabelFrame(self.my_w)

        wrapper1.pack(fill="both", expand="yes", padx=5, pady=5)
        wrapper2.pack(fill="both", expand="yes", side='left', padx=5, pady=5)
        self.wrapper3.pack(fill="both", expand="yes", side='right', padx=5, pady=5)
        wrapper4.pack(fill="both", padx=5, pady=5)

        canvas = tk.Canvas(wrapper2, bg='silver', width=800, height=200, cursor='plus #0000FF')
        canvas.pack(fill="both", expand=True)

        ctrl_frame = tk.Frame(wrapper4, bg='green', height=100)
        ctrl_frame.pack(fill="both")

        wrapper5 = tk.LabelFrame(canvas, bg='silver', width=500, height=600)
        wrapper5.pack(fill="y", expand=True, side="left", padx=10, pady=10, anchor=tk.W)

        wrapper5_1 = tk.LabelFrame(wrapper5, bg='silver')
        wrapper5_1.pack(fill="both", expand=True, side="top", padx=1, pady=1, anchor=tk.S)
        wrapper5_2 = tk.LabelFrame(wrapper5, bg='silver')
        wrapper5_2.pack(fill="both", side="bottom", padx=1, pady=1, anchor=tk.N)

        tk.Button(ctrl_frame, text='View', width=15, command=lambda: self.update_values()).place(relx=0.95, rely=0.5, anchor=tk.E)

        style = ttk.Style()

        settings = {"TScale": {
            "map": {"background":[('pressed', '!disabled', '#B2B2B2'), ('active', 'silver')]}
                               }
                    }

        style.theme_create("MyStyle", parent="clam", settings=settings)
        style.theme_use("MyStyle")

        scale_1 = ttk.Scale(wrapper5_1, from_=100, to=0, variable=self.val_a, length=500, orient="vertical", cursor='dot', takefocus=1, command=None)        
        scale_1.pack(side=tk.LEFT, padx=60, pady = 20, anchor=tk.S)
        scale_1.set(0)

        scale_2 = ttk.Scale(wrapper5_1, from_=100, to=0, variable=self.val_b, length=500, orient="vertical", cursor='dot', takefocus=1, command=None)
        scale_2.pack(side=tk.LEFT, padx=60, pady = 20, anchor=tk.S)
        scale_2.set(0)

        scale_3 = ttk.Scale(wrapper5_1, from_=100, to=0, variable=self.val_c, length=500, orient="vertical", cursor='dot', takefocus=1, command=None)        
        scale_3.pack(side=tk.LEFT, padx=60, pady = 20, anchor=tk.S)
        scale_3.set(0)

        self.val_a.trace('w', self.update_values)
        self.val_b.trace('w', self.update_values)
        self.val_c.trace('w', self.update_values)

        e1 = Entry(wrapper5_2, bg='silver', justify='center', textvariable=self.val_a)
        e1.pack(side=tk.LEFT, padx=(6,4), pady = 0, anchor=tk.S)
        e1.focus()

        e2 = Entry(wrapper5_2, bg='silver', justify='center', textvariable=self.val_b)
        e2.pack(side=tk.LEFT, padx=4, pady = 0, anchor=tk.S)

        e3 = Entry(wrapper5_2, bg='silver', justify='center', textvariable=self.val_c)
        e3.pack(side=tk.LEFT, padx=4, pady = 0, anchor=tk.S)

        self.plot_values()
        pass

        # __________________________________________________________________

    def update_values(self, *args, event=None):
        self.num_a = float(self.val_a.get())
        self.num_b = float(self.val_b.get())
        self.num_c = float(self.val_c.get())

        self.plot_values()
        return None

    def plot_values(self, *args):

        def f(x, a, b, c):  
            return a * x ** 2 + b * x + c

        xlist = np.linspace(-10, 10, num=1000)

        a = self.num_a
        b = self.num_b
        c = self.num_c

        ylist = f(xlist, a, b, c)

        figure = plt.figure(figsize = (5,4), dpi = 120)
        figure.add_subplot(111).plot(xlist, ylist)

        plt.title('Plotting Example')
        plt.xlabel('Distance / ft')
        plt.ylabel('Height / ft')
        plt.grid(True)

        plot1 = FigureCanvasTkAgg(figure, self.wrapper3)       
        plot1.get_tk_widget().grid(row = 0, column = 0)
        #.pack(fill="both", expand="yes", padx=5, pady=5)      
        return None
   
main()

Please help me to solve the problem...

0 Answers
Related