Более быстрая частота обновления с помощью plt.imshow
Я хотел бы отобразить некоторые изображения во время numpy
вычисление:
import numpy as np
import matplotlib.pyplot as plt
plt.ion() # Turn the interactive mode on.
for i in range(100):
A = np.random.randn(10,10)
plt.imshow(A)
plt.pause(0.001)
# do some other numpy computations here (they take < 1 ms)
Вместо того, чтобы отображать изображения быстро, это довольно медленно.
Я не запрашиваю 100 кадров в секунду, но я думал, что 30 кадров в секунду будут возможны, но это не так: после нескольких итераций, я близок к 2 кадрам в секунду на моем стандартном ноутбуке i5 (Windows 7 x64).
Как быстрее imshow
Частота обновления?
Заметки:
Я уже попробовал основной ответ из Fast Live Plotting в Matplotlib / PyPlot, но здесь это кажется сложным методом (с использованием
blit
параметр) для такой простой задачи, а также я не получаю 28 кадров в секунду, а только 15 кадров в секунду.Я только хочу отобразить матрицу в виде изображения: без рамки, без осей, без подзаговора и т. Д. Я полагаю, что это можно сделать быстрее, чем решение Fast Live Plotting в Matplotlib / PyPlot, может быть, не с matplotlib, а с другой библиотекой?
2 ответа
Это потому, что вы создаете новое изображение в каждой итерации, что в итоге приводит к 100 изображениям на вашей фигуре.
Рекомендованный способ создания анимации - использовать FuncAnimation
и только изменять данные изображения, вместо того, чтобы постоянно изображать новое изображение.
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
im = plt.imshow(np.random.randn(10,10))
def update(i):
A = np.random.randn(10,10)
im.set_array(A)
return im, text
ani = FuncAnimation(plt.gcf(), update, frames=range(100), interval=5, blit=False)
plt.show()
Хотя interval
установлен на 5 мс, приведенный выше код работает на моем компьютере с частотой 50 кадров в секунду. Это не пойдет быстрее, чем может. Теперь вы можете использовать блиттинг, т.е. blit=True
в этом случае я вижу 100 кадров в секунду. Это предел того, чего может достичь matplotlib, но он, конечно, будет зависеть от мощности компьютера.
Обратите внимание, что человеческий мозг не способен разрешать 100 кадров в секунду. Один говорит, что 25 - это обычная частота кадров, так что большинство фильмов также используют такую частоту кадров. Таким образом, здесь даже не нужно использовать блиттинг, так как 50 кадров в секунду больше, чем вы можете воспринимать.
Если по какой-либо причине вы хотите работать с анимацией быстрее, вам нужно использовать другие библиотеки, кроме matplotlib.
См. Например
Одно предложение в отредактированном вопросе говорит, что не должно быть никакой границы. Это достигается путем настройки размера фигуры в соответствии с аспектом изображения (квадратное изображение -> квадратная фигура) и установки всех полей на ноль
plt.figure(figsize=(5,5))
plt.subplots_adjust(0,0,1,1)
Комментарий под ответом настаивает на использовании цикла for. Это будет выглядеть
im = plt.imshow(np.random.randn(10,10))
plt.ion()
for i in range(100):
A = np.random.randn(10,10)
im.set_array(A)
plt.pause(0.005)
plt.ioff()
plt.show()
Это будет немного медленнее, чем при использовании FuncAnimation
, потому что анимация происходит вне GUI EventLop. Также обратите внимание, что реализация блитинга для такого случая - намного больше работы, как видно из Fast Live Plotting в Matplotlib / PyPlot
Я нашел гораздо более быстрое решение благодаря OpenCV. Следующий код выполняется на моем компьютере в течение 2 секунд, то есть способен отображать со скоростью 500 кадров в секунду (я знаю, что человеческий глаз не способен увидеть это, но приятно знать, что этот метод очень быстрый).
import numpy as np
import cv2
cv2.namedWindow('img', cv2.WINDOW_NORMAL)
for i in range(1000):
A = np.random.randn(10,10)
cv2.imshow("img", A)
cv2.waitKey(1) # it's needed, but no problem, it won't pause/wait