plt.imshow 刷新率更快

A faster refresh rate with 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 fps 是可能的,但事实并非如此:经过几次迭代,我在标准 i5 笔记本电脑上接近 2 fps(Windows 7 x64).

如何获得更快的imshow刷新率?

备注:

这是因为您在每次迭代中都创建了一个新图像,最终导致您的图中有 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 fps 的速度运行。它不会比它能跑得更快。您现在可以使用 blitting,即 blit=True,在这种情况下我看到 100 fps。这是matplotlib所能达到的极限,但当然会因电脑能力的不同而有所不同。

但是请注意,人脑无法解析 100 fps。有人说,25 是通常的帧率,因此大多数电影也使用这样的帧率。所以这里甚至不需要使用块传输,因为 50 fps 比您能够感知的要大。

如果出于任何原因想要更快地处理动画,则需要使用除 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 事件循环之外。另请注意,如

中所示,为这种情况实施 blitting 需要更多工作

感谢 OpenCV,我找到了一个更快的解决方案。以下代码在我的计算机上运行 2 秒,即能够 以 500 fps 呈现(我知道人眼无法看到这一点,但很高兴知道这种方法是超级快)。

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