多様性をシミュレーションする3種類バージョン Part 1


前回,ボトルネックの可視化をしてみたがその際は2種類の多様性を想定していた.今回は3種類のモデルを組んでみた.

!pip install matplotlib numpy pillow

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

from matplotlib.colors import ListedColormap
# パラメータ(ボトルネック前)
initial_num_individuals = 200  # 初期個体数
num_steps = 15  # シミュレーションの時間ステップ数(ボトルネック前まで)
grid_size = 100  # 2次元グリッドのサイズ
reproduction_rate = 1.5  # 再生産率(ボトルネック前)
death_rate = 0.1  # 個体の消滅率

# 個体の初期位置と遺伝的特徴を設定(0, 1, 2の3種類に変更)
positions = np.random.rand(initial_num_individuals, 2) * grid_size
alleles = np.random.choice([0, 1, 2], size=initial_num_individuals)

# 各アレルの割合を確認
unique, counts = np.unique(alleles, return_counts=True)
alleles_distribution = dict(zip(unique, counts))
print(f"Initial alleles distribution: {alleles_distribution}")


# プロットの準備(カラーマップを3色に対応させる)
fig, ax = plt.subplots(figsize=(6,6))
cmap = ListedColormap(['red', 'blue', 'green'])
scat = ax.scatter(positions[:,0], positions[:,1], c=alleles, cmap=cmap, s=10)
ax.set_xlim(0, grid_size)
ax.set_ylim(0, grid_size)
ax.set_title('Simulation Before Bottleneck')

def update_pre_bottleneck(frame):
    global positions, alleles
    num_individuals = len(positions)
    
    # 個体の消滅処理
    survivors = np.random.rand(num_individuals) > death_rate
    positions = positions[survivors]
    alleles = alleles[survivors]
    
    # ランダムウォークによる移動
    num_individuals = len(positions)
    positions += np.random.randn(num_individuals, 2)
    positions = np.clip(positions, 0, grid_size)

    # 再生産による個体数の増加
    num_offspring = int(len(positions) * (reproduction_rate - 1))
    if num_offspring > 0:
        parent_indices = np.random.choice(len(positions), size=num_offspring)
        offspring_positions = positions[parent_indices] + np.random.randn(num_offspring, 2)
        offspring_positions = np.clip(offspring_positions, 0, grid_size)
        offspring_alleles = alleles[parent_indices]
        positions = np.vstack((positions, offspring_positions))
        alleles = np.concatenate((alleles, offspring_alleles))

    # プロットの更新
    scat.set_offsets(positions)
    scat.set_array(alleles)
    ax.set_title(f'Simulation Before Bottleneck (Step {frame})')
    print(f'Step {frame}, Completed')
    return scat,

# アニメーションの実行と保存
ani = animation.FuncAnimation(fig, update_pre_bottleneck, frames=num_steps, interval=500, blit=True)
ani.save('pre_bottleneck_simulation_3_types.gif', writer='pillow')
plt.show()

# ボトルネック前のデータを保存
np.save('positions_before_bottleneck_3_types.npy', positions)
np.save('alleles_before_bottleneck_3_types.npy', alleles)

できたアニメーションはこちら.

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です