Behzad
Behzad

Reputation: 21

Displaying plot in Tkinter GUI frame

I want to show the plot canvas in the top right side of UI (using Tkinter python3). I wrote the following code but I got the following error:

canvas = FigureCanvasTkAgg(fig, master=root) NameError: name 'root' is not defined

My code is:

import tkinter as tk
import tkinter.ttk as ttk
from tkinter import *
import matplotlib.pyplot as plt
from  matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2Tk
from matplotlib.figure import Figure
import sys

class GUI(tk.Frame):

   def __init__(self, master = None):
       self.root = tk.Tk()
       self.root.geometry("500x500")
       tk.Frame.__init__(self, master)
       self.createWidgets()

    def start(self):
        self.root.mainloop()

    def createWidgets(self):
        fig = plt.figure(figsize=(8, 8))
        canvas = FigureCanvasTkAgg(fig, master=root)
        canvas.get_tk_widget().grid(row=0, column=1)
        canvas.show()

def main():
    appstart = GUI()
    appstart.start()

if __name__ == "__main__":
    main()

Upvotes: 1

Views: 6248

Answers (2)

1966bc
1966bc

Reputation: 1308

I made some changes to your code, deleting some unnecessary

references such as:

import tkinter.ttk as ttk

from tkinter import *

from matplotlib.figure import Figure

import sys

self.root = tk.Tk()

tk.Frame.__init__(self, master)

that you dont' use and I think only confuse yourself.

I've even simplified your script and add this code below to show to you wath is "self"

    print(type(self))

    for item in dir(self):
        print(type(item),item)

I've add even a toolbar to the plot and some data to plot something.

Regards

import tkinter as tk
import matplotlib.pyplot as plt
from  matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2Tk
import numpy as np

class GUI(tk.Tk):

    def __init__(self):
        super().__init__()
        
        self.title("Hello World")
        self.geometry("500x500")
        self.createWidgets()
        
        print(type(self))

        for item in dir(self):
            print(type(item),item)

    
    def createWidgets(self):

        t = np.arange(0, 3, .01)

        f0 = tk.Frame()
        
        fig = plt.figure(figsize=(8, 8))
        
        fig.add_subplot(111).plot(t, 2 * np.sin(2 * np.pi * t))

        canvas = FigureCanvasTkAgg(fig, f0)
        toolbar = NavigationToolbar2Tk(canvas, f0)
        toolbar.update()
        canvas._tkcanvas.pack(fill=tk.BOTH, expand=1)
        
        
        f0.pack(fill=tk.BOTH, expand=1)

def main():
    appstart = GUI()
    appstart.mainloop()
    

if __name__ == "__main__":
    main()

enter image description here

Upvotes: 2

Bryan Oakley
Bryan Oakley

Reputation: 385980

In your code you should use self.root if your intent is to use the root window:

canvas = FigureCanvasTkAgg(fig, master=self.root)

... or maybe just self, if your intent is to have it appear inside the frame. I'm not entirely sure what you are intending to do

canvas = FigureCanvasTkAgg(fig, master=self)

Somewhat unrelated, if you're explicitly creating a root window, you should be passing that to tk.Frame.__init__ rather than master.

tk.Frame.__init__(self, self.root)

Upvotes: 0

Related Questions