小能豆

通过删除/替换旧值来更新 matplotlib 子图

py

我编写了一个非常简单的代码,在 matplotlib subplot 中绘制散点图。我可以根据函数的值进行绘图x, y1plot()我想知道如果我y2通过另一个函数获得了新值,如何在图中更新它?我查看了这方面的其他帖子,有人建议在 update() 函数中使用clear()destroy(), ,delete()但都不起作用。我想保留画布和图形的设置,只用旧值替换新值。

import tkinter as tk
from matplotlib.figure import Figure
from matplotlib.backends.backend_tkagg import (FigureCanvasTkAgg, NavigationToolbar2Tk)


class Data:
    def __init__(self):
        self.x = tk.IntVar()


class SampleApp(tk.Tk):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.minsize(700, 700)
        container = tk.Frame(self)
        container.pack()

        self.data = Data()

        self.frames = {}
        for F in (PageOne, ):
            frame = F(container, self.data)
            self.frames[F] = frame
            frame.grid(row=0, column=0, sticky="nsew")

    def show_frame(self, c):
        frame = self.frames[c]
        frame.tkraise()


class PageOne(tk.Frame):
    def __init__(self, parent, data):
        super().__init__(parent)
        self.data = data

        self.button1 = tk.Button(self, text="Plot", command=self.plot)
        self.button1.pack()

        self.button2 = tk.Button(self, text="update", command=self.update)
        self.button2.pack()

        self.frame = tk.LabelFrame(self)
        self.frame.pack()

    def plot(self):
        global x
        x = [1,2,3,4,5,6,7,8,9]
        y1 = [1,2,3,4,5,6,7,8,9]

        self.figure = Figure(figsize=(4, 4))
        ax = self.figure.add_subplot(111)
        ax.scatter(x, y1)
        ax.set_title('Test')
        ax.set_xlabel('x')
        ax.set_ylabel('y')

        canvas = FigureCanvasTkAgg(self.figure, self.frame)
        canvas.draw()
        canvas.get_tk_widget().pack()
        toolbar = NavigationToolbar2Tk(canvas, self.frame)
        toolbar.pack()
        canvas.get_tk_widget().pack()

    def update(self):
        global x
        self.figure.clear()
        y2 = [1, 2, 3, 4, 5, 4, 3, 2, 1]

app = SampleApp()
app.mainloop()

阅读 20

收藏
2025-01-02

共1个答案

小能豆

这是我的操作方法,仅修改了您的update功能。

    def update(self):
        global x
        self.figure.clear()
        ax = self.figure.add_subplot(111)
        ax.set_title('Test')
        ax.set_xlabel('x')
        ax.set_ylabel('y')
        x = [1,2,3,4,5,6,7,8,9]
        y2 = [1, 2, 3, 4, 5, 4, 3, 2, 1]
        ax.scatter(x, y2)
        self.figure.canvas.draw()

以下是我使用此方法的操作方法set_data

import tkinter as tk
from matplotlib.figure import Figure
from matplotlib.backends.backend_tkagg import (FigureCanvasTkAgg, NavigationToolbar2Tk)


class Data:
    def __init__(self):
        self.x = tk.IntVar()


class SampleApp(tk.Tk):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.minsize(700, 700)
        container = tk.Frame(self)
        container.pack()

        self.data = Data()

        self.frames = {}
        for F in (PageOne, ):
            frame = F(container, self.data)
            self.frames[F] = frame
            frame.grid(row=0, column=0, sticky="nsew")

    def show_frame(self, c):
        frame = self.frames[c]
        frame.tkraise()


class PageOne(tk.Frame):
    def __init__(self, parent, data):
        super().__init__(parent)
        self.data = data

        self.button1 = tk.Button(self, text="Plot", command=self.plot)
        self.button1.pack()

        self.button2 = tk.Button(self, text="update", command=self.update)
        self.button2.pack()

        self.frame = tk.LabelFrame(self)
        self.frame.pack()


    def plot(self):
        global x
        x = [1,2,3,4,5,6,7,8,9]
        y1 = [1,2,3,4,5,6,7,8,9]

        self.figure = Figure(figsize=(4, 4))
        ax = self.figure.add_subplot(111)
        l = ax.plot(x, y1, lw=0, marker='o') # Changed here
        self.line1 = l[0] # Changed here
        ax.set_title('Test')
        ax.set_xlabel('x')
        ax.set_ylabel('y')

        canvas = FigureCanvasTkAgg(self.figure, self.frame)
        canvas.draw()
        canvas.get_tk_widget().pack()
        toolbar = NavigationToolbar2Tk(canvas, self.frame)
        toolbar.pack()
        canvas.get_tk_widget().pack()

    def update(self):
        global x
        y2 = [1, 2, 3, 4, 5, 4, 3, 2, 1]
        self.line1.set_data(x, y2) # Changed here
        self.figure.canvas.draw()  # Changed here <-- without this, won't redraw

app = SampleApp()
app.mainloop()

您的代码中有一些奇怪的东西,比如global x未使用的东西,但那是另一回事了。

2025-01-02