在 Tkinter 中嵌入 Matplotlib 不显示任何内容

Embedding Matplotlib in Tkinter doesn't dispay anything

我正在尝试使用在 class "SubplotAnimation" 中创建的图形并将其放置到我的图表页面,但它不起作用。请帮助我...在这里是我的代码(试图去掉所有不必要的东西,但还剩下一些......):

import matplotlib
matplotlib.use("TkAgg")
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2TkAgg
#import tkinter as tk
import Tkinter as tk

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.lines import Line2D
import matplotlib.animation as animation

class SubplotAnimation(animation.TimedAnimation):
    def __init__(self):
        fig = plt.figure()
        fig.set_size_inches(10, 7)
        ax2 = plt.subplot2grid((2, 2), (0, 0), colspan=2)
        ax3 = plt.subplot2grid((2, 2), (1, 0), colspan=2)

        self.t = np.linspace(0, 80, 400)
        self.x = np.cos(2 * np.pi * self.t / 10.)
        self.y = np.sin(2 * np.pi * self.t / 10.)
        self.z = 10 * self.t


        ax2.set_xlabel('y')
        ax2.set_ylabel('z')
        self.line2 = Line2D([], [], color='black')

        ax2.add_line(self.line2)

        ax2.set_xlim(0, 800)
        ax2.set_ylim(-1, 1)

        ax3.set_xlabel('x')
        ax3.set_ylabel('z')
        self.line3 = Line2D([], [], color='black')

        ax3.add_line(self.line3)

        ax3.set_xlim(0, 800)
        ax3.set_ylim(-1, 1)

        animation.TimedAnimation.__init__(self, fig, interval=50, blit=True)



    def _draw_frame(self, framedata):
        i = framedata

        self.line2.set_data(self.z[:i], self.y[:i])

        self.line3.set_data(self.z[:i], self.x[:i])


        self._drawn_artists = [self.line2, self.line3]

    def new_frame_seq(self):
        return iter(range(self.t.size))

    def _init_draw(self):
        lines = [self.line2, self.line3]
        for l in lines:
            l.set_data([], [])


#ani.save('test_sub.mp4')
    @property
    def fig(self):
        return self._fig

plt.show()





class MainPage(tk.Tk):

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

        root = tk.Tk.__init__(self, *args, **kwargs)

        tk.Tk.wm_title(self, "Heeeeelp")

        container = tk.Frame(self)

        container.pack(side="top", fill="both", expand=True)

        container.grid_rowconfigure(0, weight=1)
        container.grid_columnconfigure(0, weight=1)



        #********** FRAMES*******#

        self.frames = {} #empty..

        frame = GraphPage(container, self)

        self.frames[GraphPage] = frame

        frame.grid(row=0, column=0, sticky="nsew")

        self.show_frame(GraphPage)

    def show_frame(self, cont):

        frame = self.frames[cont]
        frame.tkraise()



class GraphPage(tk.Frame):

    def __init__(self, parent, controller):
        tk.Frame.__init__(self,parent)
        label = tk.Label(self, text="Help")
        label.grid(row=0, column=0, sticky='NW')


        ani = SubplotAnimation()
        canvas = FigureCanvasTkAgg(ani.fig, self)

        canvas.show()
        canvas.get_tk_widget().grid(row=1, column=0, rowspan=6, columnspan=3, sticky='NSEW')


app = MainPage()
app.geometry("980x640")

app.mainloop()

好的,需要做一些事情才能完成这项工作。

首先,我不太明白你为什么有代码

@property
def fig(self):
    return self._fig

但我认为您只需删除它即可。还要删除它下面的 plt.show(),因为它什么都不做。

然后需要将SubplotAnimation中的fig重命名为self.fig:

self.fig = plt.figure()
self.fig.set_size_inches(10, 7)

最后,你应该接电话给animation.TimedAnimation.__init__,把它放在canvas = FigureCanvasTkAgg(ani.fig, self)后面,然后改成

animation.TimedAnimation.__init__(ani, ani.fig, interval=50, blit=True)

我相信这就是让它发挥作用所需的所有步骤。


如果你想在你的 SubplotAnimation class 中保留动画的初始化,你也可以创建一个新函数来初始化它

def _init_animation(self):
    animation.TimedAnimation.__init__(self, self.fig, interval=50, blit=True)

并在 canvas = FigureCanvasTkAgg(...) 之后使用

调用它
ani._init_animation()