简体   繁体   English

Tkinter中的Matplotlib

[英]Matplotlib in Tkinter

I am trying to plot a graph using Matplotlib in tkinter. 我试图在tkinter中使用Matplotlib绘制图形。 Here the graph should plot all the values of 'a' in the range 0-24. 此处,该图应绘制0-24范围内的所有“ a”值。 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. 当我尝试使用matplotlib绘制相同的图时,没有tkinter时,它可以工作。 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. 但是当我尝试在带有tkinter的UI中执行此操作时,我无法进行操作。这是在没有tkinter的情况下在matplotlib中绘制图形的代码。

 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. 首先,您的App是一个包含画布的框架,但是您永远不会将其添加到根窗口中。 Because of that, your canvas will be invisible. 因此,您的画布将不可见。

Add the following code after you create an instance of App : 创建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. command属性引用一个函数。 However, you are calling the graph() function, and using the result as the value of the command attribute. 但是,您正在调用 graph()函数,并将结果用作command属性的值。

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 . 注意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. 这可能是为什么看到诸如'App' object has no attribute 'line''App' object has no attribute 'line'错误'App' object has no attribute 'line' ,因为在完全初始化所有变量之前调用了graph函数。

This documentation shows that the second explicit parameter for FigureCanvasTkAgg.__init__ should be the master. 此文档显示FigureCanvasTkAgg.__init__的第二个显式参数应该是主参数。 (It's really a keyword parameter.) (这实际上是一个关键字参数。)

So, have you tried changing that line to ... 因此,您是否尝试过将该行更改为...

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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