【问题标题】:How to make my Matplotlib graph embed in a Tkinter GUI如何让我的 Matplotlib 图形嵌入到 Tkinter GUI
【发布时间】:2019-01-29 14:45:13
【问题描述】:

我一直在搞乱 Tkinter 和嵌入式图表,根据我在网上找到的教程,我已经能够使以下 sn-p 代码完美地工作:

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

root = Tk()

# Typical matplotlib code

f = Figure(figsize = (4,3), dpi = 100)
a = f.add_subplot(111)
a.plot([1,2,4,3,5,7,6,7,8,8,9,6,7,8,7,5,6,4,3,4,3,2,1])

canvas = FigureCanvasTkAgg(f, root)
canvas.draw()
canvas.get_tk_widget().pack()
canvas._tkcanvas.pack()

root.mainloop()

问题是我无法将这个想法融入我一直在研究的程序中(Collat​​z 猜想算法)。我要做的是绘制迭代数据点的图形,但图形不显示,尽管我的脚本中的相关代码部分和示例 sn-p 是相同的。请参阅下面的代码:

#!/usr/local/bin/env python3
# -*- coding: utf-8 -*-

from tkinter import *
from tkinter import messagebox

root=Tk()
root.title("Collatz  Conjecture")

import textwrap

# Matplotlib imports

import matplotlib
matplotlib.use("TkAgg")
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg # NavigationToolbar2TkAgg
from matplotlib.figure import Figure 


 # Functions

lst = []

def collatz(num):
    lst.clear()
    while num != 1:
        lst.append(num)

        if num % 2 == 0:
            num = int(num / 2)

        else:
            num = int(3 * num + 1)

def main(event):
    num = int(input.get())

    collatz(num)


    output1.delete(1.0, END)
    output1.insert(END, lst)
    output2.delete(1.0, END)
    output2.insert(END, "Number of iterations: " + str(len(lst)))



lbl1 = Label(root, width = 20, text = "Type in number\n & press Enter")
lbl1.grid(row = 1, column = 0, sticky = W)
lbl2 = Label(root, width = 40, text = "THE COLLATZ CONJECTURE")
lbl2.grid(row = 4, column = 0)

input = Entry(root, width = 20, bg = "light grey")
input.grid(row = 1, padx = 6, sticky = E)
input.get()
input.bind("<Return>", main)

# Matplotlib Graph - typical code

f = Figure(figsize = (4,3), dpi = 100)                  # Create the figure
a = f.add_subplot(111)                                  # Add subplot
a.plot(lst)
                                            # Plot data in background

# Canvas
canvas = FigureCanvasTkAgg(f, root)
canvas.draw()
canvas.get_tk_widget().grid(row = 6, column = 0)         
canvas._tkcanvas.grid(row = 6, column = 0)

# canvas = Canvas(root, width= 350, height= 350, bg = "white")
# canvas.grid(row = 6, column = 0, padx = (5,5), pady = (5,5))

bt1 = Button(root, width = 10, text = "About")
bt1.grid(row = 7, column = 0, pady = (5,7))

output1 = Text(root, wrap = WORD, width = 50, height = 7, bg =   "light grey")  # Note word wrap attribute
output1.grid(row = 3, column = 0, padx = (5,1), sticky = W)
output2 = Text(root, width = 50, height = 1, bg = "white")
output2.grid(row = 2, column = 0, sticky = W)


def about():

    messagebox.showinfo("About", "The Collatz conjecture states that if you pick any positive whole number, and if its even, you divide it by two and if its odd, you multiply it by three and add one, and if you repeat this procedure often enough, the number that you started with will eventually reduce to one and if you play this game for long enough, your friends will eventually stop calling to see if you want to hang out ")

btn1 = Button(root, text = "About", command = about)
btn1.grid(row = 7, column = 0, pady = (5,7))


root.mainloop()

我很确定这是一个缩进问题,当有人指出我的新手错误时,我会感到非常尴尬,但我已经尝试以几乎所有可能的方式移动代码,但没有成功。

有人可以看看它,不仅告诉我我哪里错了,更重要的是,为什么错了。

【问题讨论】:

  • 数据输入后您似乎没有更新绘图。另外请重命名输入变量,因为它是内置函数名称。

标签: python matplotlib tkinter tkinter-canvas


【解决方案1】:

这个问题是根本性的。您的 tkinter 窗口循环不断刷新绘图画布,因此您看不到数据。您可以做的是将画布从窗口循环中取出并将其粘贴到主函数中。

显然还有其他/更好的解决方案,但我希望这个解决方案能突出您面临的问题。

# -*- coding: utf-8 -*-

from tkinter import *
from tkinter import messagebox

root=Tk()
root.title("Collatz  Conjecture")

import textwrap

# Matplotlib imports

import matplotlib
matplotlib.use("TkAgg")
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg # NavigationToolbar2TkAgg
from matplotlib.figure import Figure 


 # Functions

lst = []

def collatz(num):
    lst.clear()
    while num != 1:
        lst.append(num)

        if num % 2 == 0:
            num = int(num / 2)

        else:
            num = int(3 * num + 1)

def main(event):
    num = int(inp_ut.get())

    collatz(num)


    output1.delete(1.0, END)
    output1.insert(END, lst)
    output2.delete(1.0, END)
    output2.insert(END, "Number of iterations: " + str(len(lst)))
    # Generate the data and populate the canvas once. 
    f = Figure(figsize = (4,3), dpi = 100)                  # Create the figure
    a = f.add_subplot(111)                                  # Add subplot
    a.plot(lst)
    canvas = FigureCanvasTkAgg(f, root)
    canvas.draw()
    canvas.get_tk_widget().grid(row = 6, column = 0)         
    canvas._tkcanvas.grid(row = 6, column = 0)


lbl1 = Label(root, width = 20, text = "Type in number\n & press Enter")
lbl1.grid(row = 1, column = 0, sticky = W)
lbl2 = Label(root, width = 40, text = "THE COLLATZ CONJECTURE")
lbl2.grid(row = 4, column = 0)

inp_ut = Entry(root, width = 20, bg = "light grey")
inp_ut.grid(row = 1, padx = 6, sticky = E)
inp_ut.get()
inp_ut.bind("<Return>", main)

# Canvas
# canvas = Canvas(root, width= 350, height= 350, bg = "white")
# canvas.grid(row = 6, column = 0, padx = (5,5), pady = (5,5))

bt1 = Button(root, width = 10, text = "About")
bt1.grid(row = 7, column = 0, pady = (5,7))

output1 = Text(root, wrap = WORD, width = 50, height = 7, bg =   "light grey")  # Note word wrap attribute
output1.grid(row = 3, column = 0, padx = (5,1), sticky = W)
output2 = Text(root, width = 50, height = 1, bg = "white")
output2.grid(row = 2, column = 0, sticky = W)


def about():

    messagebox.showinfo("About", "The Collatz conjecture states that if you pick any positive whole number, and if its even, you divide it by two and if its odd, you multiply it by three and add one, and if you repeat this procedure often enough, the number that you started with will eventually reduce to one and if you play this game for long enough, your friends will eventually stop calling to see if you want to hang out ")

btn1 = Button(root, text = "About", command = about)
btn1.grid(row = 7, column = 0, pady = (5,7))


root.mainloop()

【讨论】:

  • 什么?我认为您的评论比这个答案更有意义。在这里,您为每个按钮按下创建一个新图形。这似乎是不受欢迎的。
猜你喜欢
  • 2021-12-04
  • 1970-01-01
  • 2011-05-03
  • 2018-01-30
  • 2012-10-23
  • 2020-06-19
  • 2014-09-26
  • 2019-01-31
  • 2019-04-08
相关资源
最近更新 更多