首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何使用matplotlib在while循环中实时绘图?

如何使用matplotlib在while循环中实时绘图?
EN

Stack Overflow用户
提问于 2012-08-09 07:36:04
回答 9查看 664.1K关注 0票数 306

我正在尝试使用OpenCV实时绘制来自摄像机的一些数据。然而,实时绘图(使用matplotlib)似乎不起作用。

我已经将问题隔离到这个简单的例子中:

代码语言:javascript
复制
fig = plt.figure()
plt.axis([0, 1000, 0, 1])

i = 0
x = list()
y = list()

while i < 1000:
    temp_y = np.random.random()
    x.append(i)
    y.append(temp_y)
    plt.scatter(i, temp_y)
    i += 1
    plt.show()

我希望这个例子能单独绘制1000个点。实际发生的情况是,窗口弹出,显示第一个点(可以),然后等待循环完成,然后填充图形的其余部分。

有什么想法为什么我一次看不到一个填充的点?

EN

回答 9

Stack Overflow用户

回答已采纳

发布于 2013-03-31 00:37:14

以下是正在讨论的代码的工作版本(至少需要2011-11-14的Matplotlib 1.1.0版本):

代码语言:javascript
复制
import numpy as np
import matplotlib.pyplot as plt

plt.axis([0, 10, 0, 1])

for i in range(10):
    y = np.random.random()
    plt.scatter(i, y)
    plt.pause(0.05)

plt.show()

注意对plt.pause(0.05)的调用,它既绘制新数据又运行图形用户界面的事件循环(允许鼠标交互)。

票数 368
EN

Stack Overflow用户

发布于 2013-03-31 08:17:21

如果你对实时绘图感兴趣,我建议你去看看matplotlib's animation API。特别是,使用blit避免在每一帧上重新绘制背景可以为您带来显著的速度提升(~10倍):

代码语言:javascript
复制
#!/usr/bin/env python

import numpy as np
import time
import matplotlib
matplotlib.use('GTKAgg')
from matplotlib import pyplot as plt


def randomwalk(dims=(256, 256), n=20, sigma=5, alpha=0.95, seed=1):
    """ A simple random walk with memory """

    r, c = dims
    gen = np.random.RandomState(seed)
    pos = gen.rand(2, n) * ((r,), (c,))
    old_delta = gen.randn(2, n) * sigma

    while True:
        delta = (1. - alpha) * gen.randn(2, n) * sigma + alpha * old_delta
        pos += delta
        for ii in xrange(n):
            if not (0. <= pos[0, ii] < r):
                pos[0, ii] = abs(pos[0, ii] % r)
            if not (0. <= pos[1, ii] < c):
                pos[1, ii] = abs(pos[1, ii] % c)
        old_delta = delta
        yield pos


def run(niter=1000, doblit=True):
    """
    Display the simulation using matplotlib, optionally using blit for speed
    """

    fig, ax = plt.subplots(1, 1)
    ax.set_aspect('equal')
    ax.set_xlim(0, 255)
    ax.set_ylim(0, 255)
    ax.hold(True)
    rw = randomwalk()
    x, y = rw.next()

    plt.show(False)
    plt.draw()

    if doblit:
        # cache the background
        background = fig.canvas.copy_from_bbox(ax.bbox)

    points = ax.plot(x, y, 'o')[0]
    tic = time.time()

    for ii in xrange(niter):

        # update the xy data
        x, y = rw.next()
        points.set_data(x, y)

        if doblit:
            # restore background
            fig.canvas.restore_region(background)

            # redraw just the points
            ax.draw_artist(points)

            # fill in the axes rectangle
            fig.canvas.blit(ax.bbox)

        else:
            # redraw everything
            fig.canvas.draw()

    plt.close(fig)
    print "Blit = %s, average FPS: %.2f" % (
        str(doblit), niter / (time.time() - tic))

if __name__ == '__main__':
    run(doblit=False)
    run(doblit=True)

输出:

代码语言:javascript
复制
Blit = False, average FPS: 54.37
Blit = True, average FPS: 438.27
票数 96
EN

Stack Overflow用户

发布于 2012-08-09 07:48:57

show可能不是最好的选择。我要做的就是使用pyplot.draw()。您可能还希望在循环中包含一个小的时间延迟(例如,time.sleep(0.05)),以便您可以看到绘图的发生。如果我对您的示例进行这些更改,它对我有效,我看到每个点一次出现一个。

票数 34
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11874767

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档