简体   繁体   中英

Matplotlib in Tkinter

I am trying to plot a graph using Matplotlib in tkinter. Here the graph should plot all the values of 'a' in the range 0-24. My code is as follows

import math
import matplotlib
matplotlib.use("TkAgg")
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
from matplotlib.figure import Figure
from tkinter import *

def att_func(d=0, n=0, z=0):
# Getting User inputs from the UI

   d = d_user.get()
   n = n_user.get()
   z = z_user.get()

   a = (-9.87 * math.sin(2 * ((2 * math.pi * (d - 81)) / 365)) + n * z)
   a_label.configure(text=a)

   return (a)

#Plotting the graph
class App:
    def __init__(self, master):
        frame = tkinter.Frame(master)
        self.nbutton_graph = tkinter.Button(frame, text="Show Graph", command=self.graph)
        self.nbutton_graph.pack()


        f = Figure(figsize=(5, 5), dpi=100)
        ab = f.add_subplot(111)
        self.line, = ab.plot(range(24))
        self.canvas = FigureCanvasTkAgg(f, self)
        self.canvas.show()
        self.canvas.get_tk_widget().pack()

   def graph(self):
       day_elevation_hrs = []
       for i in range(24):
           day_elevation_hrs.append(att_func(i, 0, 0)[0])


           self.canvas.draw()

       return
root = tkinter.Tk()
app = App(root)

# User Inputs
d_user = IntVar()
n_user = DoubleVar()
z_user = DoubleVar()


nlabel_d = Label(text="Enter d").pack()
nEntry_d = Entry(root, textvariable=d_user).pack()

nlabel_n = Label(text="Enter n").pack()
nEntry_n = Entry(root, textvariable=n_user).pack()

nlabel_z = Label(text="Enter z").pack()
nEntry_z = Entry(root, textvariable=z_user).pack()

# Displaying results

nlabel_a = Label(text="a is").pack()
a_label = Label(root, text="")
a_label.pack()

root.mainloop()

Here I am able to calculate what i need. But when I am trying to plot the same, I am unable to. I tried as many modification I could. But seems to be in a stale mate. I am sure that I am going wrong somewhere. but can't figure out where.

when i try to plot the same graph with matplotlib, with out tkinter, it works. but when I try to do it in a UI with tkinter i am unable to.. Here is the code for plotting graph in matplotlib without tkinter.

 import matplotlib.pylab as pl 
 day_elevation_hrs=[]
 for i in range(24):
    day_elevation_hrs.append(att_func(i, 0, 0)[0])

 pl.title("Elevation of a in range i")
 pl.plot(day_elevation_hrs)

Your code won't run as posted, but I can see two definite problems.

First, your App is a frame that contains a canvas, but you never add the frame to the root window. Because of that, your canvas will be invisible.

Add the following code after you create an instance of App :

app.pack(side="top", fill="both", expand=True)

Second, you are making a common mistake when defining the button to display the graph. The command attribute takes a reference to a function. However, you are calling the graph() function, and using the result as the value of the command attribute.

In other words, change this:

self.nbutton_graph = Tk.Button(self, text="Show Graph", command=self.graph())

to this:

self.nbutton_graph = Tk.Button(self, text="Show Graph", command=self.graph)

Notice the lack of () after self.graph . This could be the reason why you are seeing errors like 'App' object has no attribute 'line' , since you are calling the graph function before you fully initialize all your variables.

This documentation shows that the second explicit parameter for FigureCanvasTkAgg.__init__ should be the master. (It's really a keyword parameter.)

So, have you tried changing that line to ...

self.canvas = FigureCanvasTkAgg(f, master=master)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM