python - Can I use Animation with Matplotlib widget for pyqt4? -
i found cool animation matlibplot , want add plot widget in pyqt program. method shows regular plots in program
def plot(self): ax = self.ui.figure.add_subplot(111) ax.hold(false) ax.plot([1,2,3],[4,5,6]) self.ui.canvas.draw()
i thought add single def animation code form , call animation same above, alas no. here animation code:
import numpy np import matplotlib.pyplot plt import matplotlib.animation animation n = 100 on = 255 off = 0 vals = [on, off] # populate grid random on/off - more off on grid = np.random.choice(vals, n*n, p=[0.2, 0.8]).reshape(n, n) def update(data): global grid # copy grid since require 8 neighbors calculation # , go line line newgrid = grid.copy() in range(n): j in range(n): # compute 8-neghbor sum # using toroidal boundary conditions - x , y wrap around # simulaton takes place on toroidal surface. total = (grid[i, (j-1)%n] + grid[i, (j+1)%n] + grid[(i-1)%n, j] + grid[(i+1)%n, j] + grid[(i-1)%n, (j-1)%n] + grid[(i-1)%n, (j+1)%n] + grid[(i+1)%n, (j-1)%n] + grid[(i+1)%n, (j+1)%n])/255 # apply conway's rules if grid[i, j] == on: if (total < 2) or (total > 3): newgrid[i, j] = off else: if total == 3: newgrid[i, j] = on # update data mat.set_data(newgrid) grid = newgrid return [mat] # set animation fig, ax = plt.subplots() mat = ax.matshow(grid) ani = animation.funcanimation(fig, update, interval=50, save_count=50) plt.show()
you can use found code, change method to:
def plot(self): ax = self.ui.figure.add_subplot(111) global mat mat = ax.matshow(grid) ani = animation.funcanimation(figure, update, interval=50, save_count=50) self.ui.canvas.draw()
note, don't have use ax.hold(false)
, animation work more when using subplots(try increasing resolution [n] see difference). have such speed problems 3d plots in own project - frustrating =d
i made small sample program using class instead of global variables, maybe comes in handy:
import sys import numpy np pyqt4 import qtgui import matplotlib.pyplot plt import matplotlib.animation animation matplotlib.backends.backend_qt4agg import figurecanvasqtagg figurecanvas functools import partial class game_of_life(qtgui.qwidget): def __init__(self, n, on, off): super(game_of_life, self).__init__() self.n = n self.on = on self.off = off self.vals = [on, off] self.grid = np.random.choice(self.vals, n*n, p=[0.2, 0.8]).reshape(n, n) self.start() def start(self): self.setwindowtitle('game of life') gridlayout = qtgui.qgridlayout() self.setlayout(gridlayout) #figure , subplot figure = plt.figure() canvas = figurecanvas(figure) ax = figure.add_subplot(111) canvas.draw() self.mat = ax.matshow(self.grid) ani = animation.funcanimation(figure, self.update, interval=50, save_count=50) #button restart = qtgui.qpushbutton("restart game of life") restart.clicked.connect(partial(self.restart_animation, ax=ax, figure=figure)) gridlayout.addwidget(canvas,0,0) gridlayout.addwidget(restart, 1,0) self.show() def update(self, data): newgrid = self.grid.copy() in range(self.n): j in range(self.n): total = (self.grid[i, (j-1)%self.n] + self.grid[i, (j+1)%self.n] + self.grid[(i-1)%self.n, j] + self.grid[(i+1)%self.n, j] + self.grid[(i-1)%self.n, (j-1)%self.n] + self.grid[(i-1)%self.n, (j+1)%self.n] + self.grid[(i+1)%self.n, (j-1)%self.n] + self.grid[(i+1)%self.n, (j+1)%self.n])/255 if self.grid[i, j] == self.on: if (total < 2) or (total > 3): newgrid[i, j] = self.off else: if total == 3: newgrid[i, j] = self.on self.mat.set_data(newgrid) self.grid = newgrid #simply restarts game data def restart_animation(self, ax, figure): self.grid = np.random.choice(self.vals, self.n*self.n, p=[0.2, 0.8]).reshape(self.n, self.n) self.mat = ax.matshow(self.grid) def main(): app = qtgui.qapplication(sys.argv) widget = game_of_life(100, 255, 0) #widget can implement in other layout sys.exit(app.exec_()) if __name__ == "__main__": main()
Comments
Post a Comment