开始在嵌入PyQT4 GUI的funcAnimation中工作


问题内容

从下面显示的有效Matplotlib动画代码开始,我的目标是将此动画(只是一个在屏幕上移动的圆圈)嵌入PyQT4 GUI中。

import matplotlib.pyplot as plt
from matplotlib.patches import Circle
from matplotlib import animation

fig,ax = plt.subplots()
ax.set_aspect('equal','box')
circle = Circle((0,0), 1.0)
ax.add_artist(circle)
ax.set_xlim([0,10])
ax.set_ylim([-2,2])

def animate(i):
    circle.center=(i,0)
    return circle,

anim = animation.FuncAnimation(fig,animate,frames=10,interval=100,repeat=False,blit=True)

plt.show()

我可以使用以下代码来完成此操作,但是有一个障碍:我无法直言不讳地工作。

import sys
from PyQt4 import QtGui, QtCore
from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.figure import Figure
from matplotlib.patches import Circle
from matplotlib import animation

class Window(QtGui.QDialog): #or QtGui.QWidget ???

    def __init__(self):
        super(Window, self).__init__()
        self.fig = Figure(figsize=(5,4),dpi=100)
        self.canvas = FigureCanvas(self.fig)
        self.ax = self.fig.add_subplot(111)  # create an axis
        self.ax.hold(False)  # discards the old graph
        self.ax.set_aspect('equal','box')
        self.circle = Circle((0,0), 1.0)
        self.ax.add_artist(self.circle)
        self.ax.set_xlim([0,10])
        self.ax.set_ylim([-2,2])
        self.button = QtGui.QPushButton('Animate')
        self.button.clicked.connect(self.animate)

        # set the layout
        layout = QtGui.QVBoxLayout()
        layout.addWidget(self.canvas)
        layout.addWidget(self.button)
        self.setLayout(layout)

    def animate(self):
        self.anim = animation.FuncAnimation(self.fig,self.animate_loop,frames=10,interval=100,repeat=False,blit=False)
        self.canvas.draw()

    def animate_loop(self,i):
        self.circle.center=(i,0)
        return self.circle,

def main():

    app = QtGui.QApplication(sys.argv)
    ex = Window()
    sys.exit(app.exec_())

if __name__ == '__main__':
    main()

设置时blit=True,按下Animate按钮后,出现以下错误: a.figure.canvas.restore_region(bg_cache
[a])KeyError:matplotlib.axes._subplots.AxesSubplot对象位于0x00000000095F1D30

在寻找这个错误,我找到阻击器怎么没有在Mac上工作很多帖子,但我使用的是Windows
7,我曾尝试更换self.canvas.draw()self.canvas.update(),但这并不工作。


问题答案:

一段时间后,我设法通过直接使用基础函数而不是使用动画包装器来重新创建动画:

import sys
from PyQt4 import QtGui, QtCore
from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.figure import Figure
from matplotlib.patches import Circle
from matplotlib import animation
from time import sleep

class Window(QtGui.QDialog): #or QtGui.QWidget ???

    def __init__(self):
        super(Window, self).__init__()
        self.fig = Figure(figsize=(5, 4), dpi=100)
        self.canvas = FigureCanvas(self.fig)
        self.ax = self.fig.add_subplot(111)  # create an axis
        self.ax.hold(False)  # discards the old graph
        self.ax.set_aspect('equal', 'box')
        self.circle = Circle((0,0), 1.0, animated=True)
        self.ax.add_artist(self.circle)
        self.ax.set_xlim([0, 10])
        self.ax.set_ylim([-2, 2])
        self.button = QtGui.QPushButton('Animate')
        self.button.clicked.connect(self.animate)

        # set the layout
        layout = QtGui.QVBoxLayout()
        layout.addWidget(self.canvas)
        layout.addWidget(self.button)
        self.setLayout(layout)
        self.canvas.draw()
        self.ax_background = self.canvas.copy_from_bbox(self.ax.bbox)

    def animate(self):
        self.animate_loop(0)

    def animate_loop(self,begin):
        for i in range(begin,10):
            self.canvas.restore_region(self.ax_background)
            self.circle.center=(i,0)
            self.ax.draw_artist(self.circle)
            self.canvas.blit(self.ax.bbox)
            self.canvas.flush_events()
            sleep(0.1)

def main():

    app = QtGui.QApplication(sys.argv)
    ex = Window()
    ex.show()
    sys.exit(app.exec_())

if __name__ == '__main__':
    main()

也许这对您有用。