使用matplotlib中的blit或动画进行实时绘制

c9qzyr3d  于 2023-03-19  发布在  其他
关注(0)|答案(1)|浏览(200)

尽量简短快速。我有一个散点图,我想在live的for循环中做。所以我有这个:

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
import random
import time

x = range(1000,12000,100)
sample = random.sample(range(110),110)

plt.style.use("seaborn")
t_start = time.time()
for idx,measurement in enumerate(sample):
    plt.scatter(x[idx],measurement , color='black')
    print('Mean Frame Rate: %.3gFPS' % ((idx + 1) / (time.time() - t_start)))
    plt.pause(0.05)

plt.show()

它实际上是工作的,但是当我达到高x时,它变得越来越慢,实际上,我认为它对于测量的现场绘图来说不是很美观。

我知道人们使用blit()或animation.FuncAnimation(),但老实说,我尝试过,认为它在我的情况下只对这类数据不起作用。

[编辑]
当我说当我达到高x时它变慢了,我的fps从开始的30下降到结束的5-6。我在这里读到super_solution同样的问题,但不能应用解决方案...

wfypjpf4

wfypjpf41#

大多数链接代码依赖于不需要重绘的东西,如轴,或者屏幕上的线和点的数量保持不变。
在你的例子中,坐标轴改变了,所有的点每秒钟都改变了位置,并且添加了新的点,这意味着matplotlib必须在每一帧上栅格化整个屏幕。
你可以做一件事来加速这个光栅化,那就是通过在一次调用中聚集散射点来减少你必须在每一帧上“刷新”的“轴”的数量。

import numpy as np
import matplotlib
matplotlib.use('QTAgg')
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
import random
import time

x = range(1000,12000,100)
sample = random.sample(range(110),110)
xs = np.array(x)
ys = np.array(sample)

plt.style.use("seaborn")
s = None
t_start = time.time()
for idx,measurement in enumerate(sample):
    t1 = time.perf_counter()
    if s is not None:
        s.remove()  # remove all scatter points
    s = plt.scatter(xs[:idx],ys[:idx] , color='black')  # new scatter contains all points
    t2 = time.perf_counter()
    plt.pause(max(0.0001, 0.05-(t2-t1)))
    print('Mean Frame Rate: %.3gFPS' % (1/(time.perf_counter()-t1)))

plt.show()

帧速率总是恒定在20fps,但是这有其限制,实际上在帧速率开始降低到20fps以下之前,每帧只能绘制几千个点。
sleep实际上对于获得特定的fps是不可靠的,因为它将休眠至少所需的持续时间,您应该更正休眠间隔以获得准确的帧速率。

相关问题