threading problems

I need to have a plot window hang around and be occasionally updated by my script as it does things. I've been looking through examples and have not been able to get anything to work.

My current approach, inspired by strip_chart_demo.py and others in the animation examples, is:

import gobject, matplotlib, sys
matplotlib.use('GTKAgg')
import matplotlib.pylab as pylab
import threading, time, random

class PylabThread(threading.Thread):
   def __init__(self):
     threading.Thread.__init__(self)
   def update(self):
     pylab.draw()
   def run(self):
     gobject.idle_add(self.update)
     pylab.plot([random.random() for i in xrange(1000)])
     pylab.show()

if __name__ == "__main__":
   p = PylabThread()
   p.start()

   i = 0
   while True:
     print i
     i += 1
     time.sleep(.5)

Running this, however, yields the odd behavior that you only get numbers printed every half second (as you should) if you move the mouse (or hit keys, or otherwise generate events) within the plot window!

What's going on, and how can I fix this?

Thanks!

dan

Use the gtk mainloop and do your figure updates in a timeout add or a
idle handler (as suggested in the animation tutorial at
http://www.scipy.org/Cookbook/Matplotlib/Animations

import gobject
import numpy as np
import matplotlib
matplotlib.use('GTKAgg')

import matplotlib.pyplot as plt

fig = plt.figure()
ax = fig.add_subplot(111)
line, = ax.plot(np.random.rand(10))
ax.set_ylim(0, 1)

def update():
    line.set_ydata(np.random.rand(10))
    fig.canvas.draw_idle()
    return True # return False to terminate the updates

gobject.timeout_add(100, update) # you can also use idle_add to
update when gtk is idle
plt.show()

···

On Thu, Jun 19, 2008 at 1:40 PM, Daniel Ashbrook <anjiro@...2052...> wrote:

I need to have a plot window hang around and be occasionally updated by
my script as it does things. I've been looking through examples and have
not been able to get anything to work.

My current approach, inspired by strip_chart_demo.py and others in the
animation examples, is:

John Hunter wrote:

Use the gtk mainloop and do your figure updates in a timeout add or a
idle handler (as suggested in the animation tutorial at
http://www.scipy.org/Cookbook/Matplotlib/Animations

Excellent, thanks. Your sample code adapted nicely; appended below for posterity.

dan

import gobject
import numpy as np
import matplotlib
matplotlib.use('GTKAgg')
import matplotlib.pyplot as plt
import threading, time

class PylabThread(threading.Thread):
   def __init__(self):
     threading.Thread.__init__(self)
     self.fig = plt.figure()
     ax = self.fig.add_subplot(111)
     self.line, = ax.plot(np.random.rand(10))
     ax.set_ylim(0, 1)
   def update(self):
     self.line.set_ydata(np.random.rand(10))
     self.fig.canvas.draw_idle()
     return True # return False to terminate the updates
   def run(self):
     gobject.timeout_add(100, self.update) # you can also use idle_add to update when gtk is idle
     plt.show()

if __name__ == "__main__":
   p = PylabThread()
   p.start()

   i = 0
   while True:
     print "%.2f: %d" % (time.time(), i)
     i += 1
     time.sleep(.5)

I don't think this is what you want. gtk is already threaded. By
doing things in the gtk mainloop, you are using their threading. You
are asking for a world of pain if you try and mix in python threading
unless you really know what you are doing. The point of the example
is that you don't need to use python threads. All your printing and
figure updating can be done in function calls activated by the gtk
loop.

JDH

···

On Thu, Jun 19, 2008 at 2:30 PM, Daniel Ashbrook <anjiro@...2052...> wrote:

John Hunter wrote:

Use the gtk mainloop and do your figure updates in a timeout add or a
idle handler (as suggested in the animation tutorial at
http://www.scipy.org/Cookbook/Matplotlib/Animations

Excellent, thanks. Your sample code adapted nicely; appended below for
posterity.

John Hunter wrote:

I don't think this is what you want. gtk is already threaded. By
doing things in the gtk mainloop, you are using their threading. You
are asking for a world of pain if you try and mix in python threading
unless you really know what you are doing. The point of the example
is that you don't need to use python threads. All your printing and
figure updating can be done in function calls activated by the gtk
loop.

Ok, I think I see your point. Let me explain what I'm after, then. I'm doing some distributed computing and need to have a pylab process running remotely that accepts plotting commands. The issue is that the show() command takes over the main thread of execution, so I can't have my listening process running. Essentially I need to:

1) Pop up a figure()
2) Start the drawing loop
3) Start the socket listener
4) When the listener gets commands, execute them (plot, etc)

Is this something that I can do?

Thanks,

dan

Daniel Ashbrook wrote:

The issue is that the
show() command takes over the main thread of execution, so I can't have
my listening process running. Essentially I need to:

1) Pop up a figure()
2) Start the drawing loop
3) Start the socket listener
4) When the listener gets commands, execute them (plot, etc)

Is this something that I can do?
Thanks,
dan

I've been running into _exactly_ this issue for the past few weeks trying to
get matplotlib windows to behave a bit more like Matlab plots (or other
tools). I'm pretty new to Python and threaded GUIs (trying to come up to
speed)... maybe it's obvious to others more experienced about how to do
these things, but hard for us to explain the problem. I'll try to explain
the desired/expected behavior from a Matlab user point of view:

When using Matlab, one often creates plots in interactive (command line)
operations, or when calling scripts (m-files). But multiple plot windows
can be left open/running, and all other operations can proceed as normally -
that is, there is no blocking, and the windows behave as independent
entities - always active and not affecting behavior of other windows at all.
For example, one can run a script that creates a few plots, edit the script,
run it again, and have both the original plot windows and the new ones up at
the same time for comparision. It's the blocking behavior of show() that is
most perplexing. (While GTK may be threaded, matplotlib's show() doesn't
behave that way...)

There's a post on osdir.com from 2004 where John posted example code of how
to use the underlying GTK functions for a show() that's unique to each
window's thread, rather than the the matplotlib show() which appears to take
over (block) the entire Python process until the window is closed:

http://osdir.com/ml/python.matplotlib.general/2004-07/msg00070.html

I've seen this question come up in several posts without adequate answers,
until I came across that one. It would be great if we (or someone) can
write up a summary of this and get it into the Matplotlib docs. (Point me
in the right direction and I'll make an attempt.)

(Nice plotting tool, by the way, John et al. Good work.)
Thanks,
Scott

···

--
View this message in context: http://www.nabble.com/threading-problems-tp18015447p18050529.html
Sent from the matplotlib - users mailing list archive at Nabble.com.

Scott,

I think that for interactive work such as you describe, ipython -pylab pretty well solves the problem, and provides window behavior like matlab's.

Ipython is a big help when working with python even when you are not plotting. It is easy to install, and you don't have to learn much to start using it to good advantage. See http://ipython.scipy.org/moin/

Eric

SRH wrote:

···

Daniel Ashbrook wrote:

The issue is that the show() command takes over the main thread of execution, so I can't have my listening process running. Essentially I need to:

1) Pop up a figure()
2) Start the drawing loop
3) Start the socket listener
4) When the listener gets commands, execute them (plot, etc)

Is this something that I can do?
Thanks,
dan

I've been running into _exactly_ this issue for the past few weeks trying to
get matplotlib windows to behave a bit more like Matlab plots (or other
tools). I'm pretty new to Python and threaded GUIs (trying to come up to
speed)... maybe it's obvious to others more experienced about how to do
these things, but hard for us to explain the problem. I'll try to explain
the desired/expected behavior from a Matlab user point of view:

When using Matlab, one often creates plots in interactive (command line)
operations, or when calling scripts (m-files). But multiple plot windows
can be left open/running, and all other operations can proceed as normally -
that is, there is no blocking, and the windows behave as independent
entities - always active and not affecting behavior of other windows at all. For example, one can run a script that creates a few plots, edit the script,
run it again, and have both the original plot windows and the new ones up at
the same time for comparision. It's the blocking behavior of show() that is
most perplexing. (While GTK may be threaded, matplotlib's show() doesn't
behave that way...)

There's a post on osdir.com from 2004 where John posted example code of how
to use the underlying GTK functions for a show() that's unique to each
window's thread, rather than the the matplotlib show() which appears to take
over (block) the entire Python process until the window is closed:

http://osdir.com/ml/python.matplotlib.general/2004-07/msg00070.html

I've seen this question come up in several posts without adequate answers,
until I came across that one. It would be great if we (or someone) can
write up a summary of this and get it into the Matplotlib docs. (Point me
in the right direction and I'll make an attempt.)

(Nice plotting tool, by the way, John et al. Good work.)
Thanks,
Scott

Yes, exactly. Those of you trying to make this work may want to read
http://matplotlib.sf.net/interactive.html .

···

On Sun, Jun 22, 2008 at 12:31 AM, Eric Firing <efiring@...202...> wrote:

Scott,

I think that for interactive work such as you describe, ipython -pylab
pretty well solves the problem, and provides window behavior like matlab's.

John Hunter-4 wrote:

I think that for interactive work such as you describe, ipython -pylab
pretty well solves the problem, and provides window behavior like
matlab's.

Yes, exactly. Those of you trying to make this work may want to read
http://matplotlib.sf.net/interactive.html .

Yes, iPython takes care of these issues in interactive use. I've been
trying to stay on mainline Python for portable application development and
was using the interactive Matlab scenario as an example of "expected"
non-blocking behavior. Interactive use isn't the end-goal for me, or, I
think, for Dan. The root issue is the need to keep other activities running
while a plot window is open, which comes back to the blocking behavior of
show().

It looks like the code linked in the previous post does the job; it just
requires getting under the hood of GTK a bit more to use a separate manager
function for each plot window. That's fine, and actually it seems it would
be preferable as the default behavior of matplotlib (though each backend
probaby requires unique code). There are other alternatives: plot to a file
and display the image in a window, which loses the zoom/pan functions in
matplotlib windows, or launch the matplotlib plot window as a separate
process or program.

Thanks,
Scott

···

--
View this message in context: http://www.nabble.com/threading-problems-tp18015447p18055354.html
Sent from the matplotlib - users mailing list archive at Nabble.com.