多様性をシミュレーションする Part 2


前回,ボトルネック前の通常の種の再生産をアニメーション化してみた.

今回はボトルネック効果が起きた後のシチュエーションを想定してコードをまとめてみた.

これにより種内の多様性が低下する過程が分かる.

!pip install matplotlib numpy pillow

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
# パラメータ(ボトルネック後)
survival_rate = 0.10  # ボトルネック後に生き残る個体の割合
num_steps = 15  # シミュレーションの時間ステップ数(ボトルネック後)
reproduction_rate = 1.5  # ボトルネック後の再生産率
death_rate = 0.1  # ボトルネック後の個体の消滅率


# ボトルネック前のデータをロード
positions = np.load('positions_before_bottleneck.npy')
alleles = np.load('alleles_before_bottleneck.npy')

# プロットの準備
fig, ax = plt.subplots(figsize=(6,6))
scat = ax.scatter(positions[:,0], positions[:,1], c=alleles, cmap='bwr', s=10)
ax.set_xlim(0, 100)
ax.set_ylim(0, 100)
ax.set_title('Simulation After Bottleneck')

def update_post_bottleneck(frame):
    global positions, alleles
    num_individuals = len(positions)
    
    if frame == 0:
        # ボトルネックイベント
        survivors = np.random.rand(num_individuals) < survival_rate
        positions = positions[survivors]  # 形状に合わせて全体を更新
        alleles = alleles[survivors]
        
        # 個体数の更新
        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, 100)

    # 再生産による個体数の回復(単一性が増える)
    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, 100)
        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 After Bottleneck (Step {frame})')
    print(f'Step {frame}, Completed')
    return scat,


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

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

コメントを残す

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