matplotlib的问题功能动画

2024-05-17 19:52:53 发布

您现在位置:Python中文网/ 问答频道 /正文

我试着用matplotlib(具体地说,康威人生游戏)做一些动画,但是在.FuncAnimation上有一些问题

我发现了不同的案例,它们部分起作用(但不是我想要的方式)或导致不同的错误。我想了解错误,并制定出一个适当的版本的代码。谢谢你的帮助!在

通过.FuncAnimation调用的函数是gameoflife,它使用变量w, h, grid更新图像。在

有关整个注释代码,请参见下面的内容。在

案例1:全局变量

如果我使用全局变量,一切正常。 在调用gameoflife(self)anim = animation.FuncAnimation(fig, gameoflife)之前,我定义了w, h, grid全局

gameoflife(self)中,我还将w, h, grid定义为全局变量

w, h, grid = "something"

def gameoflife(self):
    global w
    global h
    global grid
    .
    .
    .
    img = ax.imshow(grid)
    return img

fig, ax = plt.subplots()
plt.axis('off')
img = ax.imshow(grid)
anim = animation.FuncAnimation(fig, gameoflife)
plt.show()

如前所述,这会产生想要的动画效果。但我想去掉全局变量,因此我尝试了其他方法:

情况2:传递对象

我没有在gameoflife中将w, h, grid定义为全局变量,而是用anim = animation.FuncAniation(fig, gameoflife(w,h,grid))传递它们。在

(我知道在我的示例中,w, h, grid仍然是全局的。我在另一个没有错误的版本上工作,但是由于错误是相同的,我认为这个简单的版本应该可以做到这一点。)

这将导致以下错误:

^{pr2}$

我不理解这个错误,因为我不会用代码更改调用ax。在

w, h, grid = "something"

def gameoflife(w, h, grid):
    .
    .
    .
    img = ax.imshow(grid)
    return img

fig, ax = plt.subplots()
plt.axis('off')
img = ax.imshow(grid)
anim = animation.FuncAnimation(fig, gameoflife(w,h,grid))
plt.show()

案例3:使用fargs

传递对象

在第三种情况下,我尝试使用.FuncAnimation的“frags”参数传递w, h, grid,结果只得到第一帧。(或前两个,取决于你如何看待它。“第一”帧通过img = ax.imshow(grid))精确绘制

w, h, grid = "something"

def gameoflife(self, w, h, grid):
    .
    .
    .
    img = ax.imshow(grid)
    return img

fig, ax = plt.subplots()
plt.axis('off')
img = ax.imshow(grid)
anim = animation.FuncAnimation(fig, gameoflife, fargs=(w,h,grid))
plt.show()

完整代码

希望能得到恰当的评论;)

有两个部分(开始和结束),您可以在其中注释/取消注释部分以生成相应的案例。第一种情况是错误的。在

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

##defining grid size
w= 20
h = 20

##generating random grid
grid = np.array([[random.randint(0,1) for x in range(w)] for y in range(h)])

######
# Choose for diffrent cases
######

##Case 1: Global Variables
def gameoflife(self):
    global w
    global h
    global grid

##Case 2: Passing Objects
#def gameoflife(w, h, grid):

##Case 3: Passing Objects with fargs
#def gameoflife(self, w, h, grid):

####### Choose part over

    # wt, ht as test values for position
    # x,y to set calculation position
    wt = w-1
    ht = h-1
    x,y = -1,0 #results in 0,0 for the first postion

    # defining grid for calculation (calgrid)
    calgrid = np.array([[0 for x in range(w)] for y in range(h)])

    # testing for last position
    while y<ht or x<wt:    
        # moving position through the grid
        if x == wt:
            y +=1
            x = 0
        else:
            x += 1

        #sorrounding cells check value
        scv = 0

        #counting living cells around position x,y
        #if-else for exeptions at last column and row
        if y == ht:
            if x == wt:
                scv = grid[x-1][y-1] + grid[x][y-1] + grid[0][y-1] + grid[x-1][y] + grid[0][y] + grid[x-1][0] + grid[x][0] + grid[0][0]
            else:
                scv = grid[x-1][y-1] + grid[x][y-1] + grid[x+1][y-1] + grid[x-1][y] + grid[x+1][y] + grid[x-1][0] + grid[x][0] + grid[x+1][0]
        else:
            if x == wt:
                scv = grid[x-1][y-1] + grid[x][y-1] + grid[0][y-1] + grid[x-1][y] + grid[0][y] + grid[x-1][y+1] + grid[x][y+1] + grid[0][y+1]
            else:
                scv = grid[x-1][y-1] + grid[x][y-1] + grid[x+1][y-1] + grid[x-1][y] + grid[x+1][y] + grid[x-1][y+1] + grid[x][y+1] + grid[x+1][y+1]


        # test cell to condidions and write result in calgrid
        if grid[x][y] == 0:
            if scv == 3:
                calgrid [x][y] = 1
        else :
            if 1<scv<4:
                calgrid [x][y] = 1

    # updating grid, generating img and return it
    grid = calgrid
    img = ax.imshow(grid)
    return img


fig, ax = plt.subplots()
plt.axis('off')
img = ax.imshow(grid) #generates "first" Frame from seed
#####
# Choose vor Case
#####

## Case 1: Global Variables
anim = animation.FuncAnimation(fig, gameoflife)

## Case 2: Passing Variables
#anim = anim = animation.FuncAnimation(fig, gameoflife(w,h,grid))

## Case 3: Passing Variables with fargs
#anim = animation.FuncAnimation(fig, gameoflife, fargs=(w,h,grid))

####### Choose part over
plt.show()

坦克帮助和一切

你好,托拜厄斯


Tags: imgforif错误figpltaxgrid
1条回答
网友
1楼 · 发布于 2024-05-17 19:52:53

案例2:调用函数并将结果传递到FuncAnimation。

def gameoflife(w,h,grid):
    # ...
    return ax.imshow(grid)
anim = animation.FuncAnimation(fig, gameoflife(w,h,grid))

本质上与

^{pr2}$

这将不起作用,因为第二个参数应该是函数,而不是函数的返回(在本例中是图像)。在

为了更好地解释这一点,考虑一个简单的测试用例。g是一个函数,需要一个函数作为输入。它将返回在4处计算的函数。如果您提供一个函数f,那么一切都按预期工作,但是如果您提供函数的返回,如果返回本身不是可以计算的函数,那么它将失败。在

def f(x):
    return 3*x

def g(func):
    return func(4)

g(f)     # works as expected
g(f(2))  # throws TypeError: 'int' object is not callable

案例3:使用相同的参数反复调用函数

在下列情况下

anim = animation.FuncAnimation(fig, gameoflife, fargs=(w,h,grid))

对于动画中的每一帧,使用相同的初始参数w,h,grid调用函数gameoflife。因此,您将得到一个静态动画(绘图是动画的,但是每个帧都是相同的,因为使用了相同的参数)。在

结论。与案例1保持一致

因为案例1运行良好,我不知道为什么不使用它。一种更优雅的方法是使用一个类并使用类变量,例如在this question中。在

相关问题 更多 >