On GtkAgg, one draw bad, two draws good?

Hi,

I've run into something that I expect to be ground well covered but I
can't find anything relevant on google.

I'm on linux. When using the GtkAgg backend on matplotlib 1.1.0 (or git
head for that matter), with interactive mode on, one call to draw() only
gives me a blank window, while a second draw() immediately afterwards
will draw the requested graph. On IRC, askewchan told me it only one
draw is required under MacOSX, and it also works fine with just one draw
call if I switch to the TkAgg backend.

The following short script should demonstrate the issue (note: this is
only a problem when run as a script. It works fine on ipython, or
standard python prompt):

···

---
import time
from matplotlib import pyplot as plt

def graph():

  plt.ion()

  plt.plot(range(10), range(10,20))
  plt.draw()
  plt.draw() # blank screen if this omitted
  time.sleep(2)
  plt.plot(range(30,40), range(10,20))
  plt.draw()
  plt.draw() # second line not drawn if this omitted
  time.sleep(2)

  plt.ioff()

graph()
---

backend GTKAgg version 2.24.0
As a different but most likely related issue, th Qt4Agg backend doesn't
work even with two draw calls.

Is this a known issue? Is the script not using matplotlib as expected?
If so, is running a separate thread the intended way of showing graphs
in a non-blocking way?

Thanks,
alejandro

Hi,

I've run into something that I expect to be ground well covered but I
can't find anything relevant on google.

I'm on linux. When using the GtkAgg backend on matplotlib 1.1.0 (or git
head for that matter), with interactive mode on, one call to draw() only
gives me a blank window, while a second draw() immediately afterwards
will draw the requested graph. On IRC, askewchan told me it only one
draw is required under MacOSX, and it also works fine with just one draw
call if I switch to the TkAgg backend.

This does not have a simple answer. The basic problem is a collision between event-driven programming (the gui toolkit) and nice, simple sequential programming such as in your script. The plotting commands essentially register requests with the gui toolkit, and the toolkit executes them when it gets around to it. It won't do it during a time.sleep(). Typically, it has to be waiting for input, because that is when the mainloop is checking to see if there is anything that needs to be done.

The following short script should demonstrate the issue (note: this is
only a problem when run as a script. It works fine on ipython, or
standard python prompt):

Try removing *all* your "draw" commands, and replace the calls to time.sleep(2) with plt.pause(2). That works for me on gtkagg, qt4agg, wxagg, and tkagg. plt.pause() calls the event loop while waiting, instead of just freezing everything like sleep() does.

Eric

···

On 02/25/2012 03:54 AM, Alejandro Dubrovsky wrote:

---
import time
from matplotlib import pyplot as plt

def graph():

  plt.ion()

  plt.plot(range(10), range(10,20))
  plt.draw()
  plt.draw() # blank screen if this omitted
  time.sleep(2)
  plt.plot(range(30,40), range(10,20))
  plt.draw()
  plt.draw() # second line not drawn if this omitted
  time.sleep(2)

  plt.ioff()

graph()
---

backend GTKAgg version 2.24.0
As a different but most likely related issue, th Qt4Agg backend doesn't
work even with two draw calls.

Is this a known issue? Is the script not using matplotlib as expected?
If so, is running a separate thread the intended way of showing graphs
in a non-blocking way?

Thanks,
alejandro

------------------------------------------------------------------------------
Virtualization& Cloud Management Using Capacity Planning
Cloud computing makes use of virtualization - but cloud computing
also focuses on allowing computing to be delivered as a service.
http://www.accelacomm.com/jaw/sfnl/114/51521223/
_______________________________________________
Matplotlib-users mailing list
Matplotlib-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/matplotlib-users

Hi,

I've run into something that I expect to be ground well covered but I
can't find anything relevant on google.

I'm on linux. When using the GtkAgg backend on matplotlib 1.1.0 (or git
head for that matter), with interactive mode on, one call to draw() only
gives me a blank window, while a second draw() immediately afterwards
will draw the requested graph. On IRC, askewchan told me it only one
draw is required under MacOSX, and it also works fine with just one draw
call if I switch to the TkAgg backend.

This does not have a simple answer. The basic problem is a collision
between event-driven programming (the gui toolkit) and nice, simple
sequential programming such as in your script. The plotting commands
essentially register requests with the gui toolkit, and the toolkit
executes them when it gets around to it. It won't do it during a
time.sleep(). Typically, it has to be waiting for input, because that
is when the mainloop is checking to see if there is anything that needs
to be done.

Ah, good explanation.

The following short script should demonstrate the issue (note: this is
only a problem when run as a script. It works fine on ipython, or
standard python prompt):

Try removing *all* your "draw" commands, and replace the calls to
time.sleep(2) with plt.pause(2). That works for me on gtkagg, qt4agg,
wxagg, and tkagg. plt.pause() calls the event loop while waiting,
instead of just freezing everything like sleep() does.

Yes, that works here too. It works even in non-interactive mode. Thank you.

I tried replacing all the draws in my program with plt.pause(0.01), and
it worked fine on GtkAgg, but when I tried it in QtAgg, it went to blank
screen mode. But upping it to 0.05 worked on both. So I went trawling
through code.

pause, through some intermediaries, seems to call flush_events, which
does the interfacing to the corresponding toolkit telling it to process
events, and then calls time.sleep for 0.01 seconds. It does this until
the total slept time matches or exceeds what you specify. And it seems
that Qt needs two separate rounds to get everything done. So a call like
plt.pause(0.015) works well

The time.sleep calls from pause seem unnecessary for the people like me
that just want to use pause as a get events processed signals. It would
be good if flush_events had a direct interface.

(writing this so that maybe it gets picked up by a search engine)

···

On 02/26/12 06:25, Eric Firing wrote:

On 02/25/2012 03:54 AM, Alejandro Dubrovsky wrote: