Более быстрая частота обновления с помощью plt.imshow - PullRequest
0 голосов
/ 15 ноября 2018

Я хотел бы отобразить некоторые изображения во время вычисления 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 кадров в секунду .

  • Я хочу отображать матрицу только как изображение : без рамки, без осей, без подзаговора и т. Д., Я думаю, это можно сделать быстрее, чем решение Быстрое графическое представление в Matplotlib / PyPlot , может быть, не с Matplotlib, а с другой библиотекой?

enter image description here

Ответы [ 2 ]

0 голосов
/ 16 ноября 2018

Я нашел гораздо более быстрое решение благодаря 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
0 голосов
/ 15 ноября 2018

Это потому, что вы создаете новое изображение в каждой итерации, что в итоге приводит к 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. Также обратите внимание, что реализация блитинга для такого случая - намного больше работы, как видно из Быстрое графическое представление в Matplotlib / PyPlot

...