Здесь нужно отметить несколько вещей.
blit=True
не используется при очистке промежуточных осей. Это либо не вступит в силу, либо вы получите неправильные метки на осях.
Это было бы полезно, только если границы осей не меняются от рамы к раме. Однако в нормальной гистограмме, где все больше и больше данных анимируется, это обязательно должно быть так, иначе ваши столбцы либо вырастут из осей, либо вы не увидите младшие числа в начале. В качестве альтернативы вы можете построить нормализованную гистограмму (то есть график плотности).
Кроме того, interval=1
не является полезным. Вы не сможете анимировать 4 сюжета с частотой кадров 1 миллисекунда в любой нормальной системе. Matplotlib слишком медленный для этого. Однако учтите, что человеческий мозг обычно не может разрешать частоту кадров выше примерно 25 кадров в секунду, то есть 40 мс, в любом случае. Это, вероятно, частота кадров, к которой нужно стремиться (хотя matplotlib может этого не достичь)
Так что способ настроить это просто через
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
x1 = np.random.normal(-2.5, 1, 10000)
def update(curr):
ax.clear()
ax.hist(x1[:curr], bins=np.arange(-6,2,0.5))
ax.set_title('n={}'.format(curr))
fig, ax = plt.subplots()
a = animation.FuncAnimation(fig, update, frames=len(x1), interval=40, repeat=False, blit=False)
plt.show()
Если вы чувствуете, что хотите быстрее достичь конечного числа элементов в списке, используйте меньше кадров. Например. для анимации в 25 раз быстрее, показывать только каждое 25-е состояние,
a = animation.FuncAnimation(fig, update, frames=np.arange(0, len(x1)+1, 25),
interval=40, repeat=False, blit=False)
Этот код работает с частотой кадров 11 кадров в секунду (интервал ~ 85 мс), поэтому он медленнее, чем указано, что, в свою очередь, означает, что мы могли бы напрямую установить interval=85
.
Для увеличения частоты кадров можно использовать блиттинг.
Для этого вам нужно вообще не обновлять пределы осей. Для дальнейшей оптимизации вы можете предварительно рассчитать все гистограммы, чтобы показать. Однако обратите внимание, что пределы осей не должны изменяться, поэтому мы устанавливаем их в начале, что приводит к другому графику.
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
x1 = np.random.normal(-2.5, 1, 10000)
bins = np.arange(-6,2,0.5)
hist = np.empty((len(x1), len(bins)-1))
for i in range(len(x1)):
hist[i, :], _ = np.histogram(x1[:i], bins=bins)
def update(i):
for bar, y in zip(bars, hist[i,:]):
bar.set_height(y)
text.set_text('n={}'.format(i))
return list(bars) + [text]
fig, ax = plt.subplots()
ax.set_ylim(0,hist.max()*1.05)
bars = ax.bar(bins[:-1], hist[0,:], width=np.diff(bins), align="edge")
text = ax.text(.99,.99, "", ha="right", va="top", transform=ax.transAxes)
ani = animation.FuncAnimation(fig, update, frames=len(x1), interval=1, repeat=False, blit=True)
plt.show()
Выполнение этого кода дает мне частоту кадров 215 кадров в секунду (4,6 мс на кадр), поэтому мы можем установить interval
на 4,6 мс.