Python实现的matplotlib动画演示之细胞自动机

作者:小小明-代码实体 时间:2022-05-23 15:49:09 

* 上有个有意思的话题叫细胞自动机:https://en.wikipedia.org/wiki/Cellular_automaton

在20世纪70年代,一种名为生命游戏的二维细胞自动机变得广为人知,特别是在早期的计算机界。由约翰 · 康威发明,马丁 · 加德纳在《科学美国人》的一篇文章中推广,其规则如下:

  1. Any live cell with fewer than two live neighbours dies, as if caused by underpopulation.

  2. Any live cell with two or three live neighbours lives on to the next generation.

  3. Any live cell with more than three live neighbours dies, as if by overpopulation.

  4. Any dead cell with exactly three live neighbours becomes a live cell, as if by reproduction.

总结就是:任何活细胞在有两到三个活邻居时能活到下一代,否则死亡。任何有三个活邻居的死细胞会变成活细胞,表示繁殖。

在Conway’s Game of Life中,展示了几种初始状态:

Python实现的matplotlib动画演示之细胞自动机

下面我们用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]]

Python实现的matplotlib动画演示之细胞自动机

可以看到已经成功的打印出了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]]

Python实现的matplotlib动画演示之细胞自动机

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)

Python实现的matplotlib动画演示之细胞自动机

然后我们画一下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)

Python实现的matplotlib动画演示之细胞自动机

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())

Python实现的matplotlib动画演示之细胞自动机

这种动画生成速度较慢,好处是可以导出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)

Python实现的matplotlib动画演示之细胞自动机

来源:https://blog.csdn.net/as604049322/article/details/124309635

标签:python,matplotlib,动画
0
投稿

猜你喜欢

  • Tensorflow累加的实现案例

    2023-04-15 22:55:50
  • django富文本编辑器的实现示例

    2021-02-02 06:20:33
  • 2个asp获取安全字符串的方法

    2007-10-19 15:08:00
  • SQL 注入式攻击的终极防范

    2011-04-03 11:21:00
  • javascript 缓冲效果实现代码 推荐

    2024-04-29 13:36:08
  • Python依赖包迁移到断网环境操作

    2021-06-27 06:58:29
  • python海龟绘图之画国旗实例代码

    2022-03-06 14:57:23
  • 在Django框架中设置语言偏好的教程

    2022-01-18 22:47:35
  • python求最大公约数和最小公倍数的简单方法

    2022-08-31 22:05:45
  • JQuery中对Select的option项的添加、删除、取值

    2024-04-22 12:59:14
  • Python的Flask框架中使用Flask-Migrate扩展迁移数据库的教程

    2024-01-19 06:38:45
  • 解析go语言调用约定多返回值实现原理

    2023-10-08 23:38:06
  • JavaScript编写点击查看大图的页面半透明遮罩层效果实例

    2024-02-24 03:33:08
  • python+Selenium自动化测试——输入,点击操作

    2023-08-09 07:20:50
  • Python正则表达式匹配数字和小数的方法

    2021-07-16 21:29:17
  • 基于PHP实现邮件实时通知功能

    2024-06-07 15:46:09
  • 给在DreamWeaver编写CSS的人一些习惯建议

    2007-12-25 12:10:00
  • python基础练习之几个简单的游戏

    2023-06-27 14:22:18
  • Go语言HttpRouter路由使用方法详解

    2024-05-09 14:56:31
  • 利用C#实现分布式数据库查询

    2024-01-24 18:25:28
  • asp之家 网络编程 m.aspxhome.com