1

I'm plotting a line using matplotlib and would like to update my line data as soon as new values are generated. However, once in the loop, no window appears. Even though the printed line indicates the loop is running.

Here's my code:

def inteprolate(u,X):
    ...
    return XX

# generate initial data
XX = inteprolate(u,X)

#initial plot
xdata = XX[:,0]
ydata = XX[:,1]
ax=plt.axes()  
line, = plt.plot(xdata,ydata)

# If this is in, The plot works the first time, and then pauses 
# until the window is closed.
# plt.show()

# get new values and re-plot
while True:  
    print "!"
    XX = inteprolate(u,XX)
    line.set_xdata(XX[:,0])
    line.set_ydata(XX[:,1])
    plt.draw() # no window

How do I update my plot in real-time when the plt.show() is blocking and plt.draw doesn't update/display the window?

stanri
  • 2,922
  • 3
  • 25
  • 43
  • also http://stackoverflow.com/questions/16447812/make-matplotlib-draw-only-show-new-point/16448826#16448826 – tacaswell Jul 10 '13 at 04:10

4 Answers4

1

You need to call plt.pause in your loop to give the gui a chance to process all of the events you have given it to process. If you do not it can get backed up and never show you your graph.

# get new values and re-plot
plt.ion()  # make show non-blocking
plt.show() # show the figure
while True:  
    print "!"
    XX = inteprolate(u,XX)
    line.set_xdata(XX[:,0])
    line.set_ydata(XX[:,1])
    plt.draw() # re-draw the figure
    plt.pause(.1)  # give the gui time to process the draw events

If you want to do animations, you really should learn how to use the animation module. See this awesome tutorial to get started.

tacaswell
  • 84,579
  • 22
  • 210
  • 199
0

You'll need plt.ion(). Take a look a this: pylab.ion() in python 2, matplotlib 1.1.1 and updating of the plot while the program runs. Also you can explore the Matplotlib animation classes : http://jakevdp.github.io/blog/2012/08/18/matplotlib-animation-tutorial/

Community
  • 1
  • 1
numentar
  • 1,049
  • 8
  • 21
0

I think this toy code clarify the answer of @ardoi:

import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(0,2*np.pi,num=100)
plt.ion()
for i in xrange(x.size):
    plt.plot(x[:i], np.sin(x[:i]))
    plt.xlim(0,2*np.pi)
    plt.ylim(-1,1)
    plt.draw()
    plt.clf()

Edit: The previous code display a sinusoidal function by animating it in the screen.

Alejandro
  • 3,263
  • 2
  • 22
  • 38
0

An efficient way to do the same as @Alejandro is:

import matplotlib.pyplot as plt
import numpy as np

plt.ion()
x = np.linspace(0,2*np.pi,num=100)
y = np.sin(x)

plt.xlim(0,2*np.pi)
plt.ylim(-1,1)
plot = plt.plot(x[0], y[0])[0]
for i in xrange(x.size):
    plot.set_data(x[0:i],y[0:i])
    plt.draw()
Pablo
  • 2,443
  • 1
  • 20
  • 32
  • Could you please explain what the code does? Thanks. – stanri Jul 05 '13 at 03:06
  • How is this different than the code in the OP? You are just using `set_data` in a different way. Also, using `plot` as a variable name is really bad style. – tacaswell Jul 10 '13 at 04:12