Участок не обновляется после примерки - PullRequest
0 голосов
/ 24 января 2019

Я только начал изучать GUI, используя tkinter. Я написал очень простой код. Код предполагает сначала построить значения q и t. Эта часть была успешной и здесь никаких проблем. Затем, когда я нажимаю на кнопку «Fit», она должна найти лучшее линейное соответствие и график. Он может найти лучшую линейную посадку, но не обновляет сюжет. Я не могу найти способ обновить сюжет.

from tkinter import *
from scipy.optimize import curve_fit

class Window(Frame):

    def __init__(self, master=None):
        Frame.__init__(self, master)
        self.master = master
        self.t = np.array([30,60,90,120,150,180,210,240,270,300,330,360,390,420,450,480,
             510,540,570,600,630,660,690,720,750,780,810,840,870,900,930,960,990,1020])
        self.q = np.array([781.25,413.22,255.10,173.01,125.00,94.52,73.96,59.45,48.83,40.82,
             34.63,29.74,25.83,22.63,20.00,17.80,15.94,14.36,13.01,11.83,10.81,
             9.92,9.13,8.43,7.81,7.26,6.76,6.31,5.91,5.54,5.21,4.90,4.62,4.37])
        self.popt = [0.0, 0.0]
        self.plot_window()

    def plot_window(self):
        self.master.title("DCA")
        self.pack(fill=BOTH, expand=1) 

        self.q_model = self.func(self.t, *self.popt)

        f, ax = plt.subplots()
        ax = plt.plot(self.t, self.q, 'b.') 
        ax = plt.plot(self.t, self.q_model, 'r-')

        canvas = FigureCanvasTkAgg(f, self)
        canvas.show()
        canvas.get_tk_widget().pack(side=tk.BOTTOM, fill=tk.BOTH, expand=True)        
        toolbar = NavigationToolbar2TkAgg(canvas, self)
        toolbar.update()
        canvas._tkcanvas.pack(expand=True)

        button1 = ttk.Button(self, text="Fit", command=lambda: self.fit())
        button1.pack()

    def func(self, t, a, b):
        return a*t+b

    def fit(self):
        self.popt, self.pcov = curve_fit(f=self.func, xdata=self.t, ydata=self.q)
        print(self.popt)


root = Tk()
root.geometry("700x500")
app = Window(root)
root.mainloop()

1 Ответ

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

Чтобы обновить график pyplot в tk, вам нужны две вещи:

  1. Дескриптор объекта линии, который вы хотите обновить (вы меняете данные y)
  2. Ручка к холсту для перерисовки

Я заметил несколько маленьких опечаток, поэтому исправил приведенный ниже код. Важные звонки на self.h_line.set_ydata и self.canvas.draw:

from tkinter import *

from scipy.optimize import curve_fit
import matplotlib.pyplot as plt
import numpy as np

from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2TkAgg

class Window(Frame):

    def __init__(self, master=None):
        Frame.__init__(self, master)

        self.t = np.array([30,60,90,120,150,180,210,240,270,300,330,360,390,420,450,480,
             510,540,570,600,630,660,690,720,750,780,810,840,870,900,930,960,990,1020])
        self.q = np.array([781.25,413.22,255.10,173.01,125.00,94.52,73.96,59.45,48.83,40.82,
             34.63,29.74,25.83,22.63,20.00,17.80,15.94,14.36,13.01,11.83,10.81,
             9.92,9.13,8.43,7.81,7.26,6.76,6.31,5.91,5.54,5.21,4.90,4.62,4.37])
        self.popt = [0.0, 0.0]
        self.plot_window()

    def plot_window(self):
        self.master.title("DCA")
        self.pack(side=TOP, fill=BOTH, expand=True)

        self.q_model = self.func(self.t, *self.popt)

        f, ax = plt.subplots()
        self.h_points = ax.plot(self.t, self.q, 'b.') 
        self.h_line = ax.plot(self.t, self.q_model, 'r-')[0]

        canvas = FigureCanvasTkAgg(f, self)
        canvas.show()
        canvas.get_tk_widget().pack(side=BOTTOM, fill=BOTH, expand=True)
        self.canvas = canvas
        toolbar = NavigationToolbar2TkAgg(canvas, self)
        toolbar.update()
        canvas._tkcanvas.pack(side=TOP, fill=BOTH, expand=True)

        button1 = ttk.Button(self, text="Fit", command=lambda: self.fit())
        button1.pack(side=TOP, fill=BOTH, expand=True)


    def func(self, t, a, b):
        return a*t+b

    def fit(self):
        popt, pcov = curve_fit(f=self.func, xdata=self.t, ydata=self.q)
        new_ydata = self.func(self.t, *popt)
        self.h_line.set_ydata(new_ydata)
        self.canvas.draw()

root = Tk()
app = Window(root)
root.mainloop()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...