You are on page 1of 3

Take the 2-minute tour

Chris
677 2 6 19
6 Answers
BrenBarn
53.9k 4 62 99
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?
python matplotlib while-loop
edited Aug 8 '12 at 23:44 asked Aug 8 '12 at 23:36
Is that indentation in that code block correct? If not you should clean it up. As far a I can tell the lines
following while i < 1000: should be indented until plt.show() which should not be.
Michael Mauderer Aug 8 '12 at 23:41
@Michael correct...fixed Chris Aug 8 '12 at 23:43
show is probably not the best choice for this. What I would do is use pyplot.draw() instead. You
also might want to include a small time delay (e.g., time.sleep(0.05) ) in the loop so that you can see
the plots happening. If I make these changes to your example it works for me and I see each point
appearing one at a time.
answered Aug 8 '12 at 23:48
Here's the working version of the code in question, on a more recent Matplotlib module.
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no
registration required.
real-time plotting in while loop with matplotlib
sign up

log in

tour

help

careers 2.0

add comment
add comment
Velimir Mlaker
1,329 5 15
ali_m
6,332 19 52
import time
import numpy as np
import matplotlib.pyplot as plt
fig=plt.figure()
plt.axis([0,1000,0,1])
i=0
x=list()
y=list()
plt.ion()
plt.show()
while i <1000:
temp_y=np.random.random()
x.append(i)
y.append(temp_y)
plt.scatter(i,temp_y)
i+=1
plt.draw()
time.sleep(0.05)
Note some of the changes:
1. Call plt.ion() in order to enable interactive plotting. plt.show(block=False) is no longer available.
2. Call plt.show() initially, then update the plot with plt.draw()
3. Add a time delay at the end as suggested by BrenBarn
edited Mar 30 '13 at 16:43 answered Mar 30 '13 at 16:37
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):
import numpy as np
import time
from matplotlib.pylab import subplots,close
from matplotlib import cm
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 1:
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):
"""
Visualise the simulation using matplotlib, using blit for
improved speed
"""
fig,ax = 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()
fig.canvas.draw()
if doblit:
# cache the background
background = fig.canvas.copy_from_bbox(ax.bbox)
plt = ax.plot(x,y,'o')[0]
tic = time.time()
Output:
Blit = False, average FPS: 54.37
Blit = True, average FPS: 438.27
edited Dec 18 '13 at 20:04 answered Mar 31 '13 at 0:17
add comment
add comment
Michael Mauderer
1,489 1 5 23
Scott
307 2 11
Oren
36 7
The problem seems to be that you expect plt.show() to show the window and then to return. It does
not do that. The program will stop at that point and only resume once you close the window. You should
be able to test that: If you close the window and then another window should pop up.
To resolve that problem just call plt.show() once after your loop. Then you get the complete plot.
(But not a 'real-time plotting')
You can try setting the keyword-argument block like this: plt.show(block=False) once at the
beginning and then use .draw() to update.
edited Aug 8 '12 at 23:52 answered Aug 8 '12 at 23:44
real-time plotting is really what I'm going for. I'm going to be running a 5 hour test on something and want to
see how things are progressing. Chris Aug 8 '12 at 23:48
@Chris were you able to conduct the 5 hour test? I am also looking for something similar. I am using
plyplot.pause(time_duration) to update the plot. Is there any other way to do so? Prakhar Mohan Srivastava
Apr 11 at 16:02
I know this question is old, but there's now a package available called drawnow. This provides an
interface similar to MATLAB's drawnow -- you can easily update a figure.
An example for your use case:
from pylab import arange, plt
from drawnow import drawnow
plt.ion() # enable interactivity
fig=plt.figure() # make a figure
def makeFig():
plt.scatter(x,y) # I think you meant this
x=list()
y=list()
for i in arange(1000):
temp_y=np.random.random()
x.append(i)
y.append(temp_y) # or any arbitrary update to your figure's data
i+=1
drawnow(makeFig)
answered May 9 at 15:25
None of the methods worked for me. But I have found this Real time matplotlib plot is not working while
still in a loop
All you need is to add plt.pause(0.0001) and than you could see the new plot.
edited 9 hours ago answered yesterday
Not the answer you're looking for? Browse other questions tagged python matplotlib
while-loop or ask your own question.
add comment
add comment
add comment

You might also like