Funcanimation 在 figcanvas 中不起作用

Funcanimation not working inside figcanvas

我想构建一个界面,其中包含显示某些实验结果的某些实时图表。为此,我决定结合使用 glade(UI)、gtk、python 和 matplotlib。我正在学习一些基础知识,并且能够绘制一些实时图表。

现在,我在使用 Funcanimation 制作实时动画时遇到了一些麻烦。下面,代码导入一个带有四个滚动 windows 的空地文件,我想在每个滚动 windows 中显示一些动画。我没有在 canvas(在滚动的 window 内)绘制动画,但它起作用了!但是当我尝试 运行 这个时,Funcanimation (update_line) 的回调函数甚至没有触发。实际上我在这里做错了什么。我也是 python 的新手。

谢谢

#!/usr/bin/env python
import sys
import os
import time
import psutil as p
import threading
import numpy as np
from gi.repository import Gtk
from gi.repository import GObject
from matplotlib.figure import Figure
import matplotlib.animation as animation
from matplotlib.backends.backend_gtk3cairo import FigureCanvasGTK3Cairo as FigureCanvas
import matplotlib.pyplot as plt




class windowSignals:
    def on_mainWindow_destroy(self, widget):
        Gtk.main_quit()

def main():
    builder = Gtk.Builder()
    builder.add_from_file("window.glade")
    builder.connect_signals(windowSignals())
    window = builder.get_object("mainWindow")
    sw = builder.get_object("scrolledWindow1")


    def update_line(num, data, line):
        data.pop(0)
        data.append(np.random.random())
        line.set_ydata(data)

        return line,


    fig1 = plt.figure()
    data = [0.0 for i in xrange(100)]
    l, = plt.plot(data, 'r-')

    plt.ylim(-1, 1)
    line_ani = animation.FuncAnimation(fig1, update_line, 25, fargs=(data, l), interval=50, blit=True)
    can = FigureCanvas(fig1)
    sw.add_with_viewport(can)
    can.draw()

    window.show_all()
    Gtk.main()

if __name__ == "__main__":
    main()

非常感谢@ImportanceOfBeingErnest,他 deserves credit 提供了 post 中基本正确的所有内容 :)

这里是您的代码的一个稍微修改过的可运行版本(没有 Glade),它在 GTK 应用程序中使用 FuncAnimation。

三点注意事项:

  • 以免对象(及其计时器)被垃圾回收。

  • FigureCanvas 应该在 FuncAnimation 之前创建,因为 FuncAnimation 通过调用 fig.canvas.new_timer() 创建了一个计时器。如果尚未创建 canvas,则 fig.canvas 为 None,您会得到一个 AttributeError.

  • 如果 Gtk 不是您的默认后端,请在此处使用 matplotlib.figure.Figure 而不是 plt.figure


import numpy as np
from gi.repository import Gtk
from gi.repository import GObject
from matplotlib.figure import Figure
from matplotlib.backends.backend_gtk3cairo import FigureCanvasGTK3Cairo as FigureCanvas
import matplotlib.pyplot as plt
import matplotlib.animation as animation

class MyApp(object):
    def __init__(self):
        window = Gtk.Window()
        window.connect("delete-event", Gtk.main_quit)
        window.set_default_size(400, 400)
        sw = Gtk.ScrolledWindow()
        window.add(sw)

        self.fig = fig = Figure()
        self.canvas = FigureCanvas(fig)
        sw.add_with_viewport(self.canvas)

        ax = fig.add_subplot(111)
        data = np.zeros(100)
        self.line, = ax.plot(data, 'r-')
        ax.set_ylim(-1, 1)
        self.ani = animation.FuncAnimation(
            self.fig, self.update_line, interval=100, frames=50, repeat=True)

        window.show_all()

    def update_line(self, *args):
        data = 2*(np.random.random(100)-0.5)
        self.line.set_ydata(data)
        self.canvas.draw()
        return True

if __name__ == "__main__":
    app = MyApp()
    Gtk.main()