Dmtlant commited on
Commit
f1e60b9
·
verified ·
1 Parent(s): 932e9d2

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +48 -36
app.py CHANGED
@@ -4,6 +4,7 @@ import matplotlib.pyplot as plt
4
  import random
5
  from scipy.stats import entropy as scipy_entropy
6
  import time
 
7
 
8
  # --- НАСТРОЙКИ ---
9
  seqlen = 60
@@ -12,6 +13,7 @@ min_run, max_run = 1, 2
12
  ANGLE_MAP = {'A': 60.0, 'C': 180.0, 'G': -60.0, 'T': -180.0, 'N': 0.0}
13
  bases = ['A', 'C', 'G', 'T']
14
 
 
15
  def find_local_min_runs(profile, min_run=1, max_run=2):
16
  result = []
17
  N = len(profile)
@@ -28,7 +30,7 @@ def find_local_min_runs(profile, min_run=1, max_run=2):
28
 
29
  def bio_mutate(seq):
30
  r = random.random()
31
- if r < 0.70: # Точечная мутация
32
  idx = random.randint(0, len(seq)-1)
33
  orig = seq[idx]
34
  prob = random.random()
@@ -39,18 +41,18 @@ def bio_mutate(seq):
39
  else:
40
  newbase = random.choice([b for b in bases if b != orig])
41
  seq = seq[:idx] + newbase + seq[idx+1:]
42
- elif r < 0.80: # Инсерция короткого блока
43
  idx = random.randint(0, len(seq)-1)
44
  ins = ''.join(random.choices(bases, k=random.randint(1, 3)))
45
  seq = seq[:idx] + ins + seq[idx:]
46
  if len(seq) > seqlen:
47
  seq = seq[:seqlen]
48
- elif r < 0.90: # Делеция
49
  if len(seq) > 4:
50
  idx = random.randint(0, len(seq)-2)
51
  dell = random.randint(1, min(3, len(seq)-idx))
52
  seq = seq[:idx] + seq[idx+dell:]
53
- else: # Блочная перестановка (инверсия)
54
  if len(seq) > 10:
55
  start = random.randint(0, len(seq)-6)
56
  end = start + random.randint(3,6)
@@ -88,8 +90,34 @@ if st.button("▶️ Запустить симуляцию"):
88
 
89
  plot_placeholder = st.empty()
90
 
91
- for step in range(steps):
92
- if step != 0:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
93
  seq = bio_mutate(seq)
94
  torsion_profile = np.array([ANGLE_MAP.get(nt, 0.0) for nt in seq])
95
  runs = find_local_min_runs(torsion_profile, min_run, max_run)
@@ -98,36 +126,20 @@ if st.button("▶️ Запустить симуляцию"):
98
  stat_entropy.append(ent)
99
  acorr = compute_autocorr(torsion_profile)
100
 
101
- # Визуализация
102
- fig, axs = plt.subplots(3, 1, figsize=(10, 8))
103
- plt.subplots_adjust(hspace=0.45)
104
- lags_shown = 6
105
-
106
- axs[0].cla()
107
- axs[1].cla()
108
- axs[2].cla()
109
-
110
- axs[0].plot(torsion_profile, color='royalblue', label="Торсионный угол")
111
  for start, end, val in runs:
112
- axs[0].axvspan(start, end, color="red", alpha=0.3)
113
- axs[0].plot(range(start, end+1), torsion_profile[start:end+1], 'ro', markersize=5)
114
- axs[0].set_ylim(-200, 200)
115
- axs[0].set_xlabel("Позиция")
116
- axs[0].set_ylabel("Торсионный угол (град.)")
117
- axs[0].set_title(f"Шаг {step}: {seq}\nЧисло машин: {len(runs)}, энтропия: {ent:.2f}")
118
- axs[0].legend()
119
-
120
- axs[1].plot(stat_bist_counts, '-o', color='crimson', markersize=4)
121
- axs[1].set_xlabel("Шаг")
122
- axs[1].set_ylabel("Число машин")
123
- axs[1].set_ylim(0, max(10, max(stat_bist_counts)+1))
124
- axs[1].set_title("Динамика: число 'биомашин'")
125
-
126
- axs[2].bar(np.arange(lags_shown), acorr[:lags_shown], color='teal', alpha=0.7)
127
- axs[2].set_xlabel("Лаг")
128
- axs[2].set_ylabel("Автокорреляция")
129
- axs[2].set_title("Автокорреляция углового профиля (структурность) и энтропия")
130
  axs[2].text(0.70, 0.70, f"Энтропия: {ent:.2f}", transform=axs[2].transAxes)
 
 
 
 
131
 
132
- plot_placeholder.pyplot(fig, clear_figure=True) # Используем clear_figure=True для плавности
133
- time.sleep(0.1) # Уменьшили задержку для плавности
 
4
  import random
5
  from scipy.stats import entropy as scipy_entropy
6
  import time
7
+ from matplotlib.animation import FuncAnimation
8
 
9
  # --- НАСТРОЙКИ ---
10
  seqlen = 60
 
13
  ANGLE_MAP = {'A': 60.0, 'C': 180.0, 'G': -60.0, 'T': -180.0, 'N': 0.0}
14
  bases = ['A', 'C', 'G', 'T']
15
 
16
+ # Функции остаются такими же
17
  def find_local_min_runs(profile, min_run=1, max_run=2):
18
  result = []
19
  N = len(profile)
 
30
 
31
  def bio_mutate(seq):
32
  r = random.random()
33
+ if r < 0.70:
34
  idx = random.randint(0, len(seq)-1)
35
  orig = seq[idx]
36
  prob = random.random()
 
41
  else:
42
  newbase = random.choice([b for b in bases if b != orig])
43
  seq = seq[:idx] + newbase + seq[idx+1:]
44
+ elif r < 0.80:
45
  idx = random.randint(0, len(seq)-1)
46
  ins = ''.join(random.choices(bases, k=random.randint(1, 3)))
47
  seq = seq[:idx] + ins + seq[idx:]
48
  if len(seq) > seqlen:
49
  seq = seq[:seqlen]
50
+ elif r < 0.90:
51
  if len(seq) > 4:
52
  idx = random.randint(0, len(seq)-2)
53
  dell = random.randint(1, min(3, len(seq)-idx))
54
  seq = seq[:idx] + seq[idx+dell:]
55
+ else:
56
  if len(seq) > 10:
57
  start = random.randint(0, len(seq)-6)
58
  end = start + random.randint(3,6)
 
90
 
91
  plot_placeholder = st.empty()
92
 
93
+ # Создание фигуры и осей
94
+ fig, axs = plt.subplots(3, 1, figsize=(10, 8))
95
+ plt.subplots_adjust(hspace=0.45)
96
+
97
+ # Начальная инициализация для графиков
98
+ line1, = axs[0].plot([], [], color='royalblue', label="Торсионный угол")
99
+ runs_patch = axs[0].axvspan(0, 0, color="red", alpha=0.3)
100
+ line2, = axs[1].plot([], [], '-o', color='crimson', markersize=4)
101
+ bar = axs[2].bar([], [], color='teal', alpha=0.7)
102
+
103
+ axs[0].set_ylim(-200, 200)
104
+ axs[0].set_xlabel("Позиция")
105
+ axs[0].set_ylabel("Торсионный угол (град.)")
106
+ axs[0].set_title(f"Шаг 0: {seq}")
107
+ axs[0].legend()
108
+
109
+ axs[1].set_xlabel("Шаг")
110
+ axs[1].set_ylabel("Число машин")
111
+ axs[1].set_ylim(0, 10)
112
+ axs[1].set_title("Динамика: число 'биомашин'")
113
+
114
+ axs[2].set_xlabel("Лаг")
115
+ axs[2].set_ylabel("Автокорреляция")
116
+ axs[2].set_title("Автокорреляция углового профиля")
117
+
118
+ def update(frame):
119
+ nonlocal seq
120
+ if frame != 0:
121
  seq = bio_mutate(seq)
122
  torsion_profile = np.array([ANGLE_MAP.get(nt, 0.0) for nt in seq])
123
  runs = find_local_min_runs(torsion_profile, min_run, max_run)
 
126
  stat_entropy.append(ent)
127
  acorr = compute_autocorr(torsion_profile)
128
 
129
+ # Обновление графиков
130
+ line1.set_data(range(len(torsion_profile)), torsion_profile)
 
 
 
 
 
 
 
 
131
  for start, end, val in runs:
132
+ runs_patch.set_xy([(start, -200), (end, -200), (end, 200), (start, 200)])
133
+ line2.set_data(range(len(stat_bist_counts)), stat_bist_counts)
134
+ for i, b in enumerate(acorr[:6]):
135
+ bar[i].set_height(b)
136
+
137
+ axs[0].set_title(f"Шаг {frame}: {seq}\nЧисло машин: {len(runs)}, энтропия: {ent:.2f}")
 
 
 
 
 
 
 
 
 
 
 
 
138
  axs[2].text(0.70, 0.70, f"Энтропия: {ent:.2f}", transform=axs[2].transAxes)
139
+
140
+ return line1, runs_patch, line2, bar
141
+
142
+ ani = FuncAnimation(fig, update, frames=range(steps), blit=True, interval=100)
143
 
144
+ # Показ анимации в Streamlit
145
+ plot_placeholder.pyplot(fig)