Python实现的matplotlib动画演示之细胞自动机
作者:小小明-代码实体 发布时间:2022-05-23 15:49:09
* 上有个有意思的话题叫细胞自动机:https://en.wikipedia.org/wiki/Cellular_automaton
在20世纪70年代,一种名为生命游戏的二维细胞自动机变得广为人知,特别是在早期的计算机界。由约翰 · 康威发明,马丁 · 加德纳在《科学美国人》的一篇文章中推广,其规则如下:
Any live cell with fewer than two live neighbours dies, as if caused by underpopulation.
Any live cell with two or three live neighbours lives on to the next generation.
Any live cell with more than three live neighbours dies, as if by overpopulation.
Any dead cell with exactly three live neighbours becomes a live cell, as if by reproduction.
总结就是:任何活细胞在有两到三个活邻居时能活到下一代,否则死亡。任何有三个活邻居的死细胞会变成活细胞,表示繁殖。
在Conway’s Game of Life中,展示了几种初始状态:
下面我们用python来模拟,首先尝试表示Beacon:
import numpy as np
import matplotlib.pyplot as plt
universe = np.zeros((6, 6), "byte")
# Beacon
universe[1:3, 1:3] = 1
universe[3:5, 3:5] = 1
print(universe)
im = plt.imshow(universe, cmap="binary")
[[0 0 0 0 0 0]
[0 1 1 0 0 0]
[0 1 1 0 0 0]
[0 0 0 1 1 0]
[0 0 0 1 1 0]
[0 0 0 0 0 0]]
可以看到已经成功的打印出了Beacon的形状,下面我们继续编写细胞自动机的演化规则:
def cellular_auto(universe):
universe_new = universe.copy()
h, w = universe.shape
for y in range(h):
for x in range(w):
neighbor_num = universe[x-1:x+2, y-1:y+2].sum()-universe[x, y]
# 任何有三个活邻居的死细胞都变成了活细胞,繁殖一样。
if universe[x, y] == 0 and neighbor_num == 3:
universe_new[x, y] = 1
# 任何有两到三个活邻居的活细胞都能活到下一代,否则就会死亡。
if universe[x, y] == 1 and neighbor_num not in (2, 3):
universe_new[x, y] = 0
return universe_new
universe = cellular_auto(universe)
print(universe)
plt.axis("off")
im = plt.imshow(universe, cmap="binary")
[[0 0 0 0 0 0]
[0 1 1 0 0 0]
[0 1 0 0 0 0]
[0 0 0 0 1 0]
[0 0 0 1 1 0]
[0 0 0 0 0 0]]
ArtistAnimation动画
基于此我们可以制作matplotlib的动画,下面直接将Blinker、Toad、Beacon都放上去:
from matplotlib import animation
import numpy as np
import matplotlib.pyplot as plt
%matplotlib notebook
def cellular_auto(universe):
universe_new = universe.copy()
h, w = universe.shape
for y in range(h):
for x in range(w):
neighbor_num = universe[x-1:x+2, y-1:y+2].sum()-universe[x, y]
# 任何有三个活邻居的死细胞都变成了活细胞,繁殖一样。
if universe[x, y] == 0 and neighbor_num == 3:
universe_new[x, y] = 1
# 任何有两到三个活邻居的活细胞都能活到下一代,否则就会死亡。
if universe[x, y] == 1 and neighbor_num not in (2, 3):
universe_new[x, y] = 0
return universe_new
universe = np.zeros((12, 12), "byte")
# Blinker
universe[2, 1:4] = 1
# Beacon
universe[4:6, 5:7] = 1
universe[6:8, 7:9] = 1
# Toad
universe[8, 2:5] = 1
universe[9, 1:4] = 1
fig = plt.figure()
plt.axis("off")
im = plt.imshow(universe, cmap="binary")
frame = []
for _ in range(2):
frame.append((plt.imshow(universe, cmap="binary"),))
universe = cellular_auto(universe)
animation.ArtistAnimation(fig, frame, interval=500, blit=True)
然后我们画一下Pulsar:
# Pulsar
universe = np.zeros((17, 17), "byte")
universe[[2, 7, 9, 14], 4:7] = 1
universe[[2, 7, 9, 14], 10:13] = 1
universe[4:7, [2, 7, 9, 14]] = 1
universe[10:13, [2, 7, 9, 14]] = 1
fig = plt.figure()
plt.axis("off")
im = plt.imshow(universe, cmap="binary")
frame = []
for _ in range(3):
frame.append((plt.imshow(universe, cmap="binary"),))
universe = cellular_auto(universe)
animation.ArtistAnimation(fig, frame, interval=500, blit=True)
FuncAnimation动画
另一种创建matplotlib动画的方法是使用FuncAnimation,完整代码:
from matplotlib import animation
import numpy as np
import matplotlib.pyplot as plt
from IPython.display import HTML
# %matplotlib notebook
def cellular_auto(universe):
universe_new = universe.copy()
h, w = universe.shape
for y in range(h):
for x in range(w):
neighbor_num = universe[x-1:x+2, y-1:y+2].sum()-universe[x, y]
# 任何有三个活邻居的死细胞都变成了活细胞,繁殖一样。
if universe[x, y] == 0 and neighbor_num == 3:
universe_new[x, y] = 1
# 任何有两到三个活邻居的活细胞都能活到下一代,否则就会死亡。
if universe[x, y] == 1 and neighbor_num not in (2, 3):
universe_new[x, y] = 0
return universe_new
def update(i=0):
global universe
im.set_data(universe)
universe = cellular_auto(universe)
return im,
# Pulsar
universe = np.zeros((17, 17), "byte")
universe[[2, 7, 9, 14], 4:7] = 1
universe[[2, 7, 9, 14], 10:13] = 1
universe[4:7, [2, 7, 9, 14]] = 1
universe[10:13, [2, 7, 9, 14]] = 1
fig = plt.figure()
plt.axis("off")
im = plt.imshow(universe, cmap="binary")
plt.show()
anim = animation.FuncAnimation(
fig, update, frames=3, interval=500, blit=True)
HTML(anim.to_jshtml())
这种动画生成速度较慢,好处是可以导出html文件:
with open("out.html", "w") as f:
f.write(anim.to_jshtml())
还可以保存MP4视频:
anim.save("out.mp4")
或gif动画:
anim.save("out.gif")
注意:保存MP4视频或GIF动画,需要事先将ffmpeg配置到环境变量中
ffmpeg下载地址:
链接: https://pan.baidu.com/s/1aioB_BwpKb6LxJs26HbbiQ?pwd=ciui
提取码: ciui
随机生命游戏
接下来,我们创建一个50*50的二维生命棋盘,并选取其中1500个位置作为初始活细胞点,我们看看最终生成的动画如何。
完整代码如下:
from matplotlib import animation
import numpy as np
import matplotlib.pyplot as plt
%matplotlib notebook
def cellular_auto(universe):
universe_new = universe.copy()
h, w = universe.shape
for y in range(1, h-1):
for x in range(1, w-1):
neighbor_num = universe[x-1:x+2, y-1:y+2].sum()-universe[x, y]
# 任何有三个活邻居的死细胞都变成了活细胞,繁殖一样。
if universe[x, y] == 0 and neighbor_num == 3:
universe_new[x, y] = 1
# 任何有两到三个活邻居的活细胞都能活到下一代,否则就会死亡。
if universe[x, y] == 1 and neighbor_num not in (2, 3):
universe_new[x, y] = 0
# 边缘置零
universe[[0, -1]] = 0
universe[:, [0, -1]] = 0
return universe_new
boardsize, pad = 50, 2
universe = np.zeros((boardsize+pad, boardsize+pad), "byte")
# 随机选取1500个点作为初始活细胞
for i in range(1500):
x, y = np.random.randint(1, boardsize+1, 2)
universe[y, x] = 1
fig = plt.figure()
plt.axis("off")
im = plt.imshow(universe, cmap="binary")
frame = []
for _ in range(200):
frame.append((plt.imshow(universe, cmap="binary"),))
universe = cellular_auto(universe)
animation.ArtistAnimation(fig, frame, interval=50, blit=True)
来源:https://blog.csdn.net/as604049322/article/details/124309635


猜你喜欢
- 1.安装pm2 : npm install pm2 -gd这时在命令行下执行pm2命令可能找不到,需要执行如下命令1.创建软链接:ln -s
- 前缀和后缀HasPrefix判断字符串s是否以prefix开头:strings.HaxPrefix(s string, prefix str
- 方法一: 在asp.net的aspx里面的源代码中 <input type="button onclick="ja
- 新闻系统、blog系统等都可能用到将动态页面生成静态页面的技巧来提高页面的访问速度,从而减轻服务器的压力,本文为大家搜集整理了ASP编程中常
- 当我们去设计数据库表结构,对操作数据库时(尤其是查表时的SQL语句),我们都需要注意数据操作的性能。这里,我们不会讲过多的SQL语句的优化,
- 最近一直忙,我们的注册页面还是在持续优化。今天抽时间分析了下数据,依然以主注册表单为例,对表单里3个区块、9个字段做了个小小出错排行;看看哪
- 本文实例讲述了python基于windows平台锁定键盘输入的方法。分享给大家供大家参考。具体分析如下:pywin32中没有BlockInp
- 使用fastapi框架开发web项目1、为什么要用fastapi?一直以来博主都是一直使用Django进行开发的,最近公司开始使用fasta
- 以下的文章主要向大家介绍的是实现MySQL远程访问的实际操作流程,以及在实现MySQL远程访问的过程中哪些的相关事项是十分重要的,以下就是文
- 前言我们今天来介绍一个js案例,本文仅供学习参考,大家谨慎使用。 我们先认识一下,什么是js逆向。JavaScript 逆向是指对 Java
- 一.使用Python为二年级的学生批量生成数学题1.1 背景我妹妹今年上二年级,她的老师今天给他们布置了一项作业:从今天起到开学,每天坚持做
- 一、网络爬虫网络爬虫又被称为网络蜘蛛(🕷️),我们可以把互联网想象成一个蜘蛛网,每一个网站都是一个节点,我们可以使用一只蜘蛛去各个网页抓取我
- Python项目打包python本身是一种脚本语音,发布的话,直接发布源代码就可以了,但是,可能有些公司并不想发布源代码,那么,就涉及到打包
- 1.循环删除 #这个是我选中其中的一个分支进行右键清空操作时进行的处理for i in range(self.tree.currentIte
- 一、创建一个进程实例化 Process 类创建一个进程对象然后调用它的 start 方法即可生成一个子进程from multiprocess
- 地图现在太常见了,几乎每天在地铁上都能看到卖地图的小贩,”09年新版北京旅游交通图,1块钱一份”,买的人多半是外地来旅游的,这些人需要地图来
- 现在的高手真是越来越多,我刚发现一个版主兄竟然在不支持数据库的ISP免费主页上使用数据库,套用QQ聊天的一句话就是:Faint!明明人家IS
- ECMAScript5为数组定义了5个迭代方法。每个方法都接收两个参数:要在每一项上运行的函数和(可选的)运行该函数的作用域对象(即影响th
- Pytorch中,变量参数,用numel得到参数数目,累加def get_parameter_number(net): tota
- 这篇文章主要介绍了Python Selenium参数配置方法解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值