我可以用动画与Matplotlib窗口小部件PyQt4中? [英] Can I use Animation with Matplotlib widget for pyqt4?

查看:345
本文介绍了我可以用动画与Matplotlib窗口小部件PyQt4中?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我发现这个Matlibplot酷动画,并希望将其添加到我的阴谋部件在PyQt的程序。这是一个成功的显示在我的程序定期地块方法

 高清图(个体经营):
    AX = self.ui.figure.add_subplot(111)
    ax.hold(假)
    ax.plot([1,2,3],[4,5,6])
    self.ui.canvas.draw()

我想我可能只是从动画code添加单个高清到我的表格,并调用动画上面一样,但很可惜没有。这里是动画code:

 导入numpy的是NP
进口matplotlib.pyplot如PLT
进口matplotlib.animation动画N = 100
ON = 255
OFF = 0
瓦尔斯= ON,OFF]#填充网格随机开/关 - 又比上
格= np.random.choice(丘壑,N * N,P = [0.2,0.8])。重塑(N,N)    高清更新(数据):
        全球网格
        #复制电网,因为我们需要8个邻居计算
        #我们一行一行
        newGrid = grid.copy()
        因为我在范围(N):
            有效范围内的(N)记者:
            #计算8 neghbor总和
            采用环形边界条件# - x和y回绕
            #使得模拟论证发生在一个环形表面的地方。
            总=(格[I,(J-1)%N] +格〔Ⅰ,第(j + 1)%N] +
                    格[(I-1)%N,j]的+格[第(i + 1)%N,j]的+
                    格[(I-1)%N,(J-1)%N] +网格[(I-1)%N,第(j + 1)%N] +
                    格[第(i + 1)%N,(J-1)%N] +格[第(i + 1)%N,第(j + 1)%N])/ 255
            #应用Conway的规则
            如果电网[I,J] == ON:
                如果(总2)或(总→3):
                    newGrid [I,J] = OFF
            其他:
                如果总== 3:
                    newGrid [I,J] = ON
        #更新数据
    mat.set_data(newGrid)
    格= newGrid
    返回[垫]#设置动画
无花果,AX = plt.subplots()
垫= ax.matshow(网格)
ANI = animation.FuncAnimation(图,更新时间间隔= 50,
                          save_count = 50)
plt.show()


解决方案

您可以使用您发现code,只是改变你的方法为:

 高清图(个体经营):
    AX = self.ui.figure.add_subplot(111)
    全球垫
    垫= ax.matshow(网格)
    ANI = animation.FuncAnimation(图,更新时间间隔= 50,save_count = 50)
    self.ui.canvas.draw()

请注意,你不必使用 ax.hold(假)键,它很可能是动画将运行得更慢用次要情节时(尝试增加分辨率[ N],看看差异)。我有3D绘图这样的速度问题,在我自己的项目 - 很沮丧= D

我在使用类,而不是全局变量,实例小程序,​​也许就派上用场了:

 进口SYS
导入numpy的是NP
从PyQt4的进口QtGui进口matplotlib.pyplot如PLT
进口matplotlib.animation动画
从matplotlib.backends.backend_qt4agg进口FigureCanvasQTAgg为FigureCanvas从functools部分进口类Game_of_life(QtGui.QWidget):
    高清__init __(自我,N,ON,OFF):
        超(Game_of_life,个体经营).__的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])。重塑(N,N)
        self.start()    高清启动(个体经营):
        self.setWindowTitle('游戏人生')
        网格布局= QtGui.QGridLayout()
        self.setLayout(网格布局)        #Figure和副区
        图= plt.figure()
        帆布= FigureCanvas(图)
        AX = figure.add_subplot(111)
        canvas.draw()        self.mat = ax.matshow(self.grid)
        ANI = animation.FuncAnimation(图,self.update,间隔= 50,save_count = 50)        #键
        重启= QtGui.QPushButton(生命的重新启动游戏)
        restart.clicked.connect(部分(self.restart_animation,AX = AX,图=图))        gridLayout.addWidget(帆布,0,0)
        gridLayout.addWidget(重新启动,1,0)        self.show()
    高清更新(自我,数据):
        newGrid = self.grid.copy()
        因为我在范围内(self.N):
            在范围(self.N)记者:
                总=(self.grid [I,(J-1)%self.N] + self.grid [Ⅰ,第(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
                如果self.grid [I,J] == self.ON:
                    如果(总2)或(总→3):
                        newGrid [I,J] = self.OFF
                其他:
                    如果总== 3:
                        newGrid [I,J] = self.ON
        self.mat.set_data(newGrid)
        self.grid = newGrid    #simply重新启动游戏数据
    高清restart_animation(个体经营,斧,图):
        self.grid = np.random.choice(self.vals,self.N * self.N,P = [0.2,0.8])。重塑(self.N,self.N)
        self.mat = ax.matshow(self.grid)
高清的main():
    应用= QtGui.QApplication(sys.argv中)
    插件= Game_of_life(100,255,0)
    #widget可以在其​​他布局实施
    sys.exit(app.exec_())如果__name__ ==__main__:
    主要()

I found this cool animation for Matlibplot and want to add it to my plot widget in a Pyqt program. This is the method that shows regular plots successfully in my 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 I could just add the single def from the animation code to my Form and call the animation the same as above, but alas no. Here is the animation code:

import numpy as np
import matplotlib.pyplot as plt 
import matplotlib.animation as animation

N = 100
ON = 255
OFF = 0
vals = [ON, OFF]

# populate grid with random on/off - more off than on
grid = np.random.choice(vals, N*N, p=[0.2, 0.8]).reshape(N, N)

    def update(data):
        global grid
        # copy grid since we require 8 neighbors for calculation
        # and we go line by line 
        newGrid = grid.copy()
        for i in range(N):
            for j in range(N):
            # compute 8-neghbor sum 
            # using toroidal boundary conditions - x and y wrap around 
            # so that the simulaton takes place on a 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 up animation
fig, ax = plt.subplots()
mat = ax.matshow(grid)
ani = animation.FuncAnimation(fig, update, interval=50,
                          save_count=50)
plt.show()

解决方案

You can use your found code, just change your 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, that you don't have to use ax.hold(False) and it is likely that animation will work more slowly when using subplots(try increasing resolution [N] to see difference). I have such speed problems with 3D plots in my own project - very frustrating =D

I made small sample program using class instead of global variables, maybe it comes in handy:

import sys
import numpy as np
from PyQt4 import QtGui

import matplotlib.pyplot as plt
import matplotlib.animation as animation
from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas

from 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 and 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()
        for i in range(self.N):
            for 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 be implement in other layout
    sys.exit(app.exec_())

if __name__ == "__main__":
    main()

这篇关于我可以用动画与Matplotlib窗口小部件PyQt4中?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆