Python 为什么我的模拟人生游戏在几秒钟内就慢下来了?该怪Matplotlib吗?
我正在用python学习OOP,所以为了好玩,今天早上我制作了一个GameOfLife模拟器。当它启动时,它以每秒约20个周期的速度运行(由于添加了Python 为什么我的模拟人生游戏在几秒钟内就慢下来了?该怪Matplotlib吗?,python,oop,matplotlib,Python,Oop,Matplotlib,我正在用python学习OOP,所以为了好玩,今天早上我制作了一个GameOfLife模拟器。当它启动时,它以每秒约20个周期的速度运行(由于添加了plt.pause(0.05)I),但在几秒钟内,它的速度降至每秒约2个周期 我无法想象这是算法本身,我也看不到任何明显的内存泄漏来源 matplotlib是否未能转储旧绘图,这是否是导致数千个重叠图像累积的问题?我尝试添加delim,但没有帮助 这其实并不重要,但我觉得我可以从答案中学到一些东西 PS如果你认为我的执行很差,那么一定要让我知道,我渴
plt.pause(0.05)
I),但在几秒钟内,它的速度降至每秒约2个周期
我无法想象这是算法本身,我也看不到任何明显的内存泄漏来源
matplotlib是否未能转储旧绘图,这是否是导致数千个重叠图像累积的问题?我尝试添加delim
,但没有帮助
这其实并不重要,但我觉得我可以从答案中学到一些东西
PS如果你认为我的执行很差,那么一定要让我知道,我渴望学习
import matplotlib.pyplot as plt
import numpy as np
from scipy.ndimage import convolve
import time
class GoL():
KERNEL = np.array([[1, 1, 1],
[1, 0, 1],
[1, 1, 1]])
def __init__(self, width, height, p=0.3):
self.width = width
self.height = height
self.matrix = np.random.choice(a=[1, 0], size=(width, height), p=[p, 1 - p])
def play(self):
self.plot()
while True:
self.cycle()
def cycle(self):
c = self.eval()
for x in range(1,self.width-1):
for y in range(1,self.height-1):
c_val = c[x,y]
if c_val == 3: self.matrix[x,y] = 1 #Alive regardless of whether cell alive or dead
elif c_val < 2: self.matrix[x,y] = 0 #Dead regardless of whether cell alive or dead
elif c_val > 3: self.matrix[x,y] = 0 #Dead regardless of whether cell alive or dead
elif self.matrix[x,y] == 1 and c_val == 2: self.matrix[x,y] = 1 #If a living cell with 2 neighours, live
else: self.matrix[x,y] = 0 #Only other option is dead with 2 neighbours; die
self.plot()
def eval(self):
c = convolve(self.matrix, GoL.KERNEL, mode='constant')
return c
def plot(self):
im = plt.imshow(self.matrix)
plt.pause(0.05)
del im #Added to see if speeds things up; it does not
在重用画布之前,应清除旧图形。可以使用matplotlib.pyplot.clf()清除当前图形():
希望这有帮助!:) 通过打印
plot
函数中的图像数量,您将看到以前调用的图像仍然存在
print ( len(plt.gca().images) )
在您的情况下,即使删除图像,该数字也会稳步增加,因为它仍然是轴的一部分,因此每次迭代都会重新绘制
最好只绘制一次图像,然后只更新其数据
class GoL():
# ...
def __init__(self, width, height, p=0.3):
self.width = width
self.height = height
self.matrix = np.random.choice(a=[1, 0], size=(width, height), p=[p, 1 - p])
self.im = plt.imshow(self.matrix)
# ....
def plot(self):
self.im.set_data(self.matrix)
plt.pause(0.05)
print len(plt.gca().images)
这将以恒定速度生成动画
关于在何处改进守则的问题,有两件事:
matplotlib.animation.FuncAnimation
,因为这样更稳定,并且允许保存终止动画import matplotlib.pyplot as plt
import numpy as np
from scipy.ndimage import convolve
import matplotlib.animation as animation
class GoL():
KERNEL = np.array([[1, 1, 1],
[1, 0, 1],
[1, 1, 1]])
def __init__(self, width, height, p=0.3):
self.width = width
self.height = height
self.matrix = np.random.choice(a=[1, 0], size=(width, height), p=[p, 1 - p])
self.im = plt.imshow(self.matrix)
def play(self):
self.plot()
self.ani= animation.FuncAnimation(plt.gcf(), self.cycle, repeat=True, interval=50 )
plt.show()
def cycle(self, n):
c = self.eval()
new = np.zeros_like(self.matrix)
new[c == 3] = 1
new[c < 2] = 0
new[c > 3] = 0
new[(self.matrix == 1) & (c == 2)] = 1
self.matrix = new
self.plot()
def eval(self):
return convolve(self.matrix, self.KERNEL, mode='constant')
def plot(self):
self.im.set_data(self.matrix)
gol = GoL(width=100,height=100)
gol.play()
导入matplotlib.pyplot作为plt
将numpy作为np导入
从scipy.ndimage导入卷积
将matplotlib.animation导入为动画
类GoL():
KERNEL=np.array([[1,1,1],
[1, 0, 1],
[1, 1, 1]])
定义初始值(自身、宽度、高度,p=0.3):
self.width=宽度
自我高度=高度
self.matrix=np.random.choice(a=[1,0],size=(宽度,高度),p=[p,1-p])
self.im=plt.imshow(self.matrix)
def播放(自我):
self.plot()
self.ani=animation.FuncAnimation(plt.gcf(),self.cycle,repeat=True,interval=50)
plt.show()
def循环(自身,n):
c=self.eval()
new=np.类零(自矩阵)
新[c==3]=1
新[c<2]=0
新[c>3]=0
新的[(self.matrix==1)和(c==2)]=1
self.matrix=新
self.plot()
def eval(自我):
返回卷积(self.matrix,self.KERNEL,mode='constant')
def绘图(自):
self.im.set_数据(self.matrix)
gol=gol(宽度=100,高度=100)
高尔夫球赛
找到答案的最佳方法是分析代码。你是在使用matplotlibsion
还是?我添加了一个更优化、运行更快的解决方案。太棒了!非常感谢。因为您已经创建了一个新的0数组,所以可以删除行new[c<2]=0
和new[c>3]=0
,我想……谢谢您,非常直接!
class GoL():
# ...
def __init__(self, width, height, p=0.3):
self.width = width
self.height = height
self.matrix = np.random.choice(a=[1, 0], size=(width, height), p=[p, 1 - p])
self.im = plt.imshow(self.matrix)
# ....
def plot(self):
self.im.set_data(self.matrix)
plt.pause(0.05)
print len(plt.gca().images)
import matplotlib.pyplot as plt
import numpy as np
from scipy.ndimage import convolve
import matplotlib.animation as animation
class GoL():
KERNEL = np.array([[1, 1, 1],
[1, 0, 1],
[1, 1, 1]])
def __init__(self, width, height, p=0.3):
self.width = width
self.height = height
self.matrix = np.random.choice(a=[1, 0], size=(width, height), p=[p, 1 - p])
self.im = plt.imshow(self.matrix)
def play(self):
self.plot()
self.ani= animation.FuncAnimation(plt.gcf(), self.cycle, repeat=True, interval=50 )
plt.show()
def cycle(self, n):
c = self.eval()
new = np.zeros_like(self.matrix)
new[c == 3] = 1
new[c < 2] = 0
new[c > 3] = 0
new[(self.matrix == 1) & (c == 2)] = 1
self.matrix = new
self.plot()
def eval(self):
return convolve(self.matrix, self.KERNEL, mode='constant')
def plot(self):
self.im.set_data(self.matrix)
gol = GoL(width=100,height=100)
gol.play()