Updating a plot as data is acquired

Hello,

I am trying to write an application that measures data from an external
device and then displays the data on a graph, updating the graph when new
measurements arrive. Searching the web has led to matplotlib and so I've
been having a go at using that for my program. After searching around on the
forums, I have had some success in implementing the functionality I am
aiming for, but the application gets very very slow the longer it runs.

I have attached the test program I wrote at the bottom of this post. The
application uses Tkinter for the GUI. Whenever you type something into the
text box at the top, the ascii code of the last character in the text is
added to the data list and plotted. The more things you type, the
application gets slower and slower.

I initially thought that the slow down might be due to the data list getting
bigger and bigger, but I no longer think that this is the case. If you
comment out line 31 (self.data.append(ord(self.text.get()[-1]))) and replace
it with something like self.data = [1, 2, 3], the application still exhibits
the same slow down with time.

Is there a 'proper' way of doing this?

Thanks,

--Amr

PS remove the comment at the bottom of the file (root.mainloop())

http://www.nabble.com/file/p23573077/pylog.py pylog.py

···

--
View this message in context: http://www.nabble.com/Updating-a-plot-as-data-is-acquired-tp23573077p23573077.html
Sent from the matplotlib - users mailing list archive at Nabble.com.

By default matplotlib overplots, meaning it keeps the old data around
in addition to the new data, so you are plotting on the i-th iteration

  0: [d0]
  1: [d0], [d0, d1][d0], [d0, d1]
  2: [d0], [d0, d1], [d0, d1, d2], ....

You probably don't see it because the new points overlap the old.

If you turn overplotting off

   ax.hold(False)

before issuing the plot commands you should not see the dramatic slowing.

You can speed up the performance further by reusing the same line object, eg

somelimit = 1000
line, = ax.plot([], [])
xs = []
ys = []
for row in mydata:
  xs.append(row['newx'])
  ys.append(row['newy'])
  if len(xs)>somelimit:
    del xs[0]
    del ys[0]
  line.set_data(xs, ys)
  ax.figure.canvas.draw()

See also the animation tutorial and examples

  http://www.scipy.org/Cookbook/Matplotlib/Animations
  http://matplotlib.sourceforge.net/examples/animation/index.html

JDH

···

On Sat, May 16, 2009 at 6:57 AM, amrbekhit <amrbekhit@...287...> wrote:

Hello,

I am trying to write an application that measures data from an external
device and then displays the data on a graph, updating the graph when new
measurements arrive. Searching the web has led to matplotlib and so I've
been having a go at using that for my program. After searching around on the
forums, I have had some success in implementing the functionality I am
aiming for, but the application gets very very slow the longer it runs.