StonedBored
StonedBored

Reputation: 47

How to plot a graph in a labelframe using tkinter and matplotlib?

I'm making a simple GUI using tkinter and matplotlib. I want to plot inside a LabelFrame, but when I try to plot again using a new entries, it overlap the new graph with the old one. How can I plot just the last graph? I'm almost sure the problem it the last lines of code or the way how I declare the frame. My plan is to have a window with more a graphs, each one in their own frame.

Here's what I have tired :

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

def main():

    root = Tk.Tk()
    gui = Window(root)
    gui.root.mainloop()

    return None
class Window:
    def __init__(self,root):
        self.root = root
        self.root.title("Overpressure Estimation")
        self.root.geometry('1400x500')

        parameters_frame =LabelFrame(self.root, text="Blast parameters", padx=20,pady=20)
        parameters_frame.pack(padx=1,pady=1)
        self.parameters_frame = parameters_frame

        graph_frame =LabelFrame(self.root, text="Graphs", padx=20,pady=20)
        graph_frame.pack(padx=10,pady=10)

        self.graph_frame = graph_frame

        self.charge = 100
        self.distance = 100
        self.kasite = 516
        self.asite = -1.45


        charge = Label(self.parameters_frame ,  text = "Charge Q (Kg)")
        self.charge_entry = Entry(self.parameters_frame ,  width = 15)
        self.charge_entry.grid(row=0, column=1)
        charge.grid(row=0, column=0)

        distance = Label(self.parameters_frame ,  text = "Distance (m)")
        self.distance_entry = Entry(self.parameters_frame ,  width = 15)
        self.distance_entry.grid(row=1, column=1)
        distance.grid(row=1, column=0)

        kasite = Label(self.parameters_frame ,  text = "Site constant (K)")
        self.kasite_entry = Entry(self.parameters_frame ,  width = 15)
        self.kasite_entry.grid(row=2, column=1)
        kasite.grid(row=2, column=0)

        asite = Label(parameters_frame ,  text = "Site exponent (a)")
        self.asite_entry = Entry(self.parameters_frame ,  width = 15)
        self.asite_entry.grid(row=3, column=1)
        asite.grid(row=3, column=0)



        button1 = Button(self.parameters_frame, text = "Calculate",command = self.update_values)
        parameters_frame.bind("<Return>", self.update_values)
        self.plot_values()
        button1.grid(row=5, column=1)
        pass

    def update_values(self, event=None):

        self.charge = int(self.charge_entry.get())
        self.distance = int(self.distance_entry.get())
        self.kasite = int(self.kasite_entry.get())
        self.asite = float(self.asite_entry.get())
        self.plot_values()
        return None

    pass

    def plot_values(self):

        # GRAPH
        z1 = [np.round(10 * np.log10((((((i/(self.charge**(1/3)))**self.asite) * self.kasite)/(0.00002))**2)),0) 
                       for i in np.arange(0.1,self.distance + 1) ]

        line_1 = [120 for i in range(1,self.distance + 1)]
        line_2 = [125 for i in range(1,self.distance + 1)]
        line_3 = [133 for i in range(1,self.distance + 1)]
        x1 = np.arange(1, self.distance + 1) 

        figure1 = plt.figure(figsize = (6,5), dpi = 100)
        figure1.add_subplot(111)

        plt.plot(z1,label="Decay Curve")
        plt.plot(x1, line_3,'b--',label="130 dbL: Maximum for Structural Damage Level" )
        plt.plot(x1, line_2,'r--',label="125 dbL: Maximum for Human Comfort Level" )
        plt.plot(x1, line_1,'g--',label="120 dbL: Annoying" )
        plt.legend()
        plt.xlabel('Distance (m)')
        plt.ylabel('Sound  Pressure Level(dBL)',labelpad=1)
        plt.title('SPL DECAY')
        plt.xscale('log')
        plt.grid(True, which="both", ls="-")

        chart = FigureCanvasTkAgg(figure1,self.graph_frame)
        chart.get_tk_widget().pack()
   
      
        return None
    pass
main()

Upvotes: 2

Views: 636

Answers (1)

imxitiz
imxitiz

Reputation: 3987

You can try this :

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

def main():

    root = Tk.Tk()
    gui = Window(root)
    gui.root.mainloop()

    return None
class Window:
    def __init__(self,root):
        self.root = root
        self.root.title("Overpressure Estimation")
        self.root.geometry('1400x500')

        parameters_frame =LabelFrame(self.root, text="Blast parameters", padx=20,pady=20)
        parameters_frame.pack(padx=1,pady=1)
        self.parameters_frame = parameters_frame

        graph_frame =LabelFrame(self.root, text="Graphs", padx=20,pady=20)
        graph_frame.pack(padx=10,pady=10)

        self.graph_frame = graph_frame

        self.charge = 100
        self.distance = 100
        self.kasite = 516
        self.asite = -1.45

        charge = Label(self.parameters_frame ,  text = "Charge Q (Kg)")
        self.charge_entry = Entry(self.parameters_frame ,  width = 15)
        self.charge_entry.grid(row=0, column=1)
        self.charge_entry.insert(0,7)
        charge.grid(row=0, column=0)

        distance = Label(self.parameters_frame ,  text = "Distance (m)")
        self.distance_entry = Entry(self.parameters_frame ,  width = 15)
        self.distance_entry.grid(row=1, column=1)
        distance.grid(row=1, column=0)
        self.distance_entry.insert(0,7)
        kasite = Label(self.parameters_frame ,  text = "Site constant (K)")
        self.kasite_entry = Entry(self.parameters_frame ,  width = 15)
        self.kasite_entry.grid(row=2, column=1)
        kasite.grid(row=2, column=0)
        self.kasite_entry.insert(0,7)
        asite = Label(parameters_frame ,  text = "Site exponent (a)")
        self.asite_entry = Entry(self.parameters_frame ,  width = 15)
        self.asite_entry.grid(row=3, column=1)
        asite.grid(row=3, column=0)
        self.asite_entry.insert(0,7)

        button1 = Button(self.parameters_frame, text = "Calculate",command = self.update_values)
        parameters_frame.bind("<Return>", self.update_values)
 
        button1.grid(row=5, column=1)
        
        self.test()
        frame=Frame(self.graph_frame)
        frame.pack()
        self.frame=frame
        chart = FigureCanvasTkAgg(self.figure1,self.frame)
        chart.get_tk_widget().pack()
    
        self.chart =chart

    def update_values(self, event=None):

        self.charge = int(self.charge_entry.get())
        self.distance = int(self.distance_entry.get())
        self.kasite = int(self.kasite_entry.get())
        self.asite = float(self.asite_entry.get())
        self.plot_values()
        return None
    
    def test(self):
        z1 = [np.round(10 * np.log10((((((i/(self.charge**(1/3)))**self.asite) * self.kasite)/(0.00002))**2)),0) for i in np.arange(0.1,self.distance + 1) ]
        line_1 = [120 for i in range(1,self.distance + 1)]
        line_2 = [125 for i in range(1,self.distance + 1)]
        line_3 = [133 for i in range(1,self.distance + 1)]
        x1 = np.arange(1, self.distance + 1) 
        figure1 = plt.figure(figsize = (6,5), dpi = 100)
        figure1.add_subplot(111)
        
        self.figure1=figure1
        plt.plot(z1,label="Decay Curve")
        plt.plot(x1, line_3,'b--',label="130 dbL: Maximum for Structural Damage Level" )
        plt.plot(x1, line_2,'r--',label="125 dbL: Maximum for Human Comfort Level" )
        plt.plot(x1, line_1,'g--',label="120 dbL: Annoying" )
        plt.legend()
        plt.xlabel('Distance (m)')
        plt.ylabel('Sound  Pressure Level(dBL)',labelpad=1)
        plt.title('SPL DECAY')
        plt.xscale('log')
        plt.grid(True, which="both", ls="-")

    def plot_values(self):
        self.test()
        self.frame.destroy()
        frame=Frame(self.graph_frame)
        frame.pack()
        self.frame=frame
        chart = FigureCanvasTkAgg(self.figure1,self.frame)
        chart.get_tk_widget().pack()

        return None
    pass
main()

We have done some trick, we have made new frame as parent frame for FigureCanvasTkAgg and if we have to create new FigureCanvasTkAgg then we can destroy parent frame and make new Frame and FigureCanvasTkAgg

Upvotes: 1

Related Questions