Как сделать мой график Matplotlib встроенным в графический интерфейс Tkinter - PullRequest
0 голосов
/ 29 января 2019

Я возился с Tkinter и встроенными графиками, и из учебника, который я нашел в сети, я смог заставить следующий фрагмент кода работать отлично:

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()

Проблема в том, что яЯ не смог включить идею в программу, над которой я работал (алгоритм гипотезы Коллатца).Я пытаюсь построить график точек данных итерации, но этот график не отображается, несмотря на тот факт, что соответствующие части кода в моем сценарии и фрагменте примера идентичны.См. Мой код ниже:

#!/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()

Я почти уверен, что это проблема с отступом, и я буду очень смущен, когда кто-то укажет на мою ошибку новичка, но я попытался переместить код впо-видимому, всеми возможными способами, но безуспешно.

Может кто-нибудь, пожалуйста, взгляните на это и скажите мне не только, где я ошибся, но, что более важно, ПОЧЕМУ это неправильно.

1 Ответ

0 голосов
/ 29 января 2019

Вопрос фундаментальный.Ваш цикл окна 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()
...