获取块传输嵌入在PyQt4的GUI funcAnimation工作 [英] Getting blitting to work in funcAnimation embedded in PyQT4 GUI
问题描述
与工作Matplotlib动画$ C $下面所示的C开始,我的目标是嵌入这个动画(这仅仅是一个在屏幕上移动圆)一个PyQt4的GUI中。
Starting with the working Matplotlib animation code shown below, my goal is to embed this animation (which is just a circle moving across the screen) within a 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()
我能够这样使用以下code来完成,但有一个障碍:我不能让块传输工作。
I am able to accomplish this using the following code, but there is one hitch: I cannot get blitting to work.
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
,之后pressing的动画按钮,我得到以下错误:
a.figure.canvas.restore_region(bg_cache [A])
KeyError异常:在0x00000000095F1D30 matplotlib.axes._subplots.AxesSubplot对象
When I set blit=True
, after pressing the Animate button I get the following error:
a.figure.canvas.restore_region(bg_cache[a])
KeyError: matplotlib.axes._subplots.AxesSubplot object at 0x00000000095F1D30
在寻找这个错误,我觉得如何的Blitting无法在Mac电脑很多帖子,但我使用的是Windows 7,我曾尝试更换 self.canvas.draw()
与 self.canvas.update()
,但这不起作用。
In searching this error, I find many posts about how blitting does not work on Macs, but I am using Windows 7. I have tried replacing self.canvas.draw()
with self.canvas.update()
, but this does not work.
推荐答案
过了一段时间,我设法重新创建而不是直接使用基础功能使用动画包装动画:
After some time I managed to recreate the animation by using the underlying functions directly and not using the animation wrapper:
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,i):
for i in range(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()
也许这将是利用你。
Maybe this will be of use to you.
这篇关于获取块传输嵌入在PyQt4的GUI funcAnimation工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!