Внутри animate()
вам нужно получить следующее состояние частично отсортированного списка, и вам необходимо соответствующим образом обновить гистограмму.
Вы получаете обновленный список, перебирая sorter
, но в зависимости от того, какой слой вложенного for loops
вы помещаете оператор yield
, ваши обновления происходят более или менее часто. В настоящее время вы можете выдать отсортированный список только один раз. Я переместил его на 1 oop вниз, но вы можете делать более частые обновления:
Обновление графика выполняется через h_bar
(См. Также этот вопрос для обновления гистограмм. в общем)
Я упустил некоторые части кода, чтобы сосредоточиться на основных вещах.
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
def bubblesort(list):
for i in range(len(list)):
for j in range(0, len(list) - i - 1):
if list[j] > list[j+1]:
list[j], list[j+1] = list[j+1], list[j]
# yield list # two elements swapped place
yield list # ith bubble loop completed
# yield list # sorted list
n = 100
unsorted_vals = np.random.randint(0, 101, size=n)
sorter = bubblesort(unsorted_vals)
fig, ax = plt.subplots(figsize=(15, 8))
ax.set_ylim(0, 100)
for key, spine in ax.spines.items():
spine.set_visible(False)
ax.set_yticks([])
ax.set_xticks([])
h_bar = ax.bar(range(len(unsorted_vals)), unsorted_vals)
def animate(x):
current_list = sorter.__next__()
for rect, h in zip(h_bar, current_list):
rect.set_height(h)
anim = animation.FuncAnimation(fig, frames=n, func=animate, repeat=False)
plt.show()
Прямо сейчас вы всегда обновляете всю гистограмму, когда нужно только обновить два элемента, которые поменялись местами, может быть, вы можете ускорить анимацию с помощью:
def bubblesort(list):
for i in range(len(list)):
for j in range(0, len(list) - i - 1):
if list[j] > list[j+1]:
list[j], list[j+1] = list[j+1], list[j]
yield list, j
def animate(x):
current_list, idx = sorter.__next__()
h_bar[idx].set_height(current_list[idx])
h_bar[idx+1].set_height(current_list[idx+1])
return h_bar