Как обновить встроенный в tkinter matplotlib? - PullRequest
0 голосов
/ 05 ноября 2018

Проблема в том, что я хочу нарисовать график, нажав на кнопку, но это не работает. Однако, когда я звоню draw из __init__, на экране появляется график.

Plotter.py

from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
from matplotlib.figure import Figure

class Plotter(FigureCanvasTkAgg):

    def __init__(self, master):

        self.figure = Figure(dpi=100)
        super().__init__(self.figure, master=master)
        self.axes = self.figure.add_subplot(111)
        self.get_tk_widget().grid(column=0, row=0, sticky='nsew')

    def draw(self):

        self.axes.clear()
        x_list = [x for x in range(0, 100)]
        y_list = [x^3 for x in x_list]
        self.axes.plot(x_list, y_list, color='y')

MainApplication.py

from tkinter import ttk 
import tkinter as tk
import plotter

class MainApplication(ttk.Frame):

    def __init__(self, master, *args, **kwargs):

        super().__init__(root)
        self.grid(column=0, row=0, sticky='nsew')

        frame = ttk.Frame(self, borderwidth=8)
        frame.grid(column=0, row=0, sticky='nsew')
        frame.rowconfigure(0, weight=1)

        notes = ttk.Notebook(frame)
        notes.grid(column=0, row=0, sticky='nsew')
        notes.rowconfigure(0, weight=1)

        page = ttk.Frame(notes)
        notes.add(page, text='Picture')


        plot = plotter.Plotter(page)
        # plot.draw() # This call updates the plot

        input_frame = ttk.Frame(self)
        input_frame.grid(column=1, row=0, sticky='nsew')

        # this binding doesn't update the plot
        button = ttk.Button(input_frame, text='Plot', \
                            command=lambda: plot.draw())
        button.grid(column=0, row=4, columnspan=2, sticky='ew')


root = tk.Tk() 
MainApplication(root)
root.mainloop()

Ответы [ 2 ]

0 голосов
/ 05 ноября 2018

Лично я написал бы это в одном классе, чтобы мы могли использовать атрибуты класса и методы для легкого управления всем. Также вам не нужна лямбда здесь. Просто сохраните ссылку на командную кнопку, а не лямбда-вызов. Тем не менее, вы также перезаписывали метод draw для FigureCanvasTkAgg, поэтому измените метод draw() на что-то другое.

from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
from matplotlib.figure import Figure
from tkinter import ttk 
import tkinter as tk


class MainApplication(tk.Tk):
    def __init__(self):
        tk.Tk.__init__(self)
        notes = ttk.Notebook(self)
        notes.grid(column=0, row=0, sticky='nsew')
        notes.rowconfigure(0, weight=1)
        self.page = ttk.Frame(notes)
        notes.add(self.page, text='Picture')
        self.plotter()
        input_frame = ttk.Frame(self)
        input_frame.grid(column=1, row=0, sticky='nsew')

        button = ttk.Button(input_frame, text='Plot', command=self.new_draw)
        button.grid(column=0, row=4, columnspan=2, sticky='ew')

    def plotter(self):
        self.figure = Figure(dpi=100)
        self.plot_canvas = FigureCanvasTkAgg(self.figure, self.page)
        self.axes = self.figure.add_subplot(111)
        self.plot_canvas.get_tk_widget().grid(column=0, row=0, sticky='nsew')

    def new_draw(self):
        self.axes.clear()
        x_list = [x for x in range(0, 100)]
        y_list = [x^3 for x in x_list]
        self.axes.plot(x_list, y_list, color='y')
        self.plot_canvas.draw_idle()

MainApplication().mainloop()
0 голосов
/ 05 ноября 2018

Вы переписали метод canvas 'draw, не реализовав его заново. Но так как вы все равно не хотите обновлять свой график на каждом событии розыгрыша, я бы предложил вызвать метод, чтобы обновить график по-другому, например, draw_lists. Внутри draw_lists вам нужно будет вызвать метод draw canvas (или, в данном случае, лучше draw_idle).

from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
from matplotlib.figure import Figure

class Plotter(FigureCanvasTkAgg):

    def __init__(self, master):

        self.figure = Figure(dpi=100)
        super().__init__(self.figure, master=master)
        self.axes = self.figure.add_subplot(111)
        self.get_tk_widget().grid(column=0, row=0, sticky='nsew')

    def draw_lists(self):

        self.axes.clear()
        x_list = [x for x in range(0, 100)]
        y_list = [x^3 for x in x_list]
        self.axes.plot(x_list, y_list, color='y')
        self.draw_idle()



from tkinter import ttk 
import tkinter as tk


class MainApplication(ttk.Frame):

    def __init__(self, master, *args, **kwargs):

        super().__init__(root)
        self.grid(column=0, row=0, sticky='nsew')

        frame = ttk.Frame(self, borderwidth=8)
        frame.grid(column=0, row=0, sticky='nsew')
        frame.rowconfigure(0, weight=1)

        notes = ttk.Notebook(frame)
        notes.grid(column=0, row=0, sticky='nsew')
        notes.rowconfigure(0, weight=1)

        page = ttk.Frame(notes)
        notes.add(page, text='Picture')


        plot = Plotter(page)

        input_frame = ttk.Frame(self)
        input_frame.grid(column=1, row=0, sticky='nsew')

        # this binding doesn't update the plot
        button = ttk.Button(input_frame, text='Plot', \
                            command=lambda: plot.draw_lists())
        button.grid(column=0, row=4, columnspan=2, sticky='ew')


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