# How do I plot in real-time in a while loop using matplotlib?

### Question

I am trying to plot some data from a camera in real time using OpenCV. However, the real-time plotting (using matplotlib) doesn't seem to be working.

I've isolated the problem into this simple example:

``````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()
``````

I would expect this example to plot 1000 points individually. What actually happens is that the window pops up with the first point showing (ok with that), then waits for the loop to finish before it populates the rest of the graph.

Any thoughts why I am not seeing points populated one at a time?

1
202
4/5/2019 1:00:32 PM

Here's the working version of the code in question (requires at least version Matplotlib 1.1.0 from 2011-11-14):

``````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()
``````

Note some of the changes:

1. Call `plt.pause(0.05)` to both draw the new data and it runs the GUI's event loop (allowing for mouse interaction).
276
4/2/2018 4:56:33 PM

If you're interested in realtime plotting, I'd recommend looking into matplotlib's animation API. In particular, using `blit` to avoid redrawing the background on every frame can give you substantial speed gains (~10x):

``````#!/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')
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)
``````

Output:

``````Blit = False, average FPS: 54.37
Blit = True, average FPS: 438.27
``````