Is Tkinter-matplotlib using Threads?

There were several question on the user's list in the recent past
reporting hangs and similar when using TkAgg backend & interactive
mode.

It is known that Tkinter doesn't play well with threading, as long as
one isn't done very carefully.

It could be that matplotlib has implemented it in a way not safe for
Tkinter. This applies if there are Tkinter methods called from
threads other than those which imported Tkinter.

It results in unpredicatable behaviour with exactly the features
reported: Hang-ups, blankening, partial hangup of part of the threads.

Is a rewrite of the Tk interactive code necessary?

Friedrich

There were several question on the user's list in the recent past
reporting hangs and similar when using TkAgg backend& interactive
mode.

It is known that Tkinter doesn't play well with threading, as long as
one isn't done very carefully.

It could be that matplotlib has implemented it in a way not safe for
Tkinter. This applies if there are Tkinter methods called from
threads other than those which imported Tkinter.

It results in unpredicatable behaviour with exactly the features
reported: Hang-ups, blankening, partial hangup of part of the threads.

Is a rewrite of the Tk interactive code necessary?

I don't see any use of the threading module in backend_tkagg.py or backend_bases.py. Is that what you are referring to?

Ipython -pylab does use threads (version 0.10), but is intended to avoid problems by running all user code in a single separate thread.

Eric

···

On 10/01/2010 09:40 AM, Friedrich Romstedt wrote:

Friedrich

2010/10/2 Eric Firing <efiring@...229...>:

There were several question on the user's list in the recent past
reporting hangs and similar when using TkAgg backend& interactive
mode.

It is known that Tkinter doesn't play well with threading, as long as
one isn't done very carefully.

It could be that matplotlib has implemented it in a way not safe for
Tkinter. This applies if there are Tkinter methods called from
threads other than those which imported Tkinter.

It results in unpredicatable behaviour with exactly the features
reported: Hang-ups, blankening, partial hangup of part of the threads.

Is a rewrite of the Tk interactive code necessary?

I don't see any use of the threading module in backend_tkagg.py or
backend_bases.py. Is that what you are referring to?

Ipython -pylab does use threads (version 0.10), but is intended to avoid
problems by running all user code in a single separate thread.

I just dived a bit into the matplotlib source code, and come up with
partial answers:

When interactive mode is on, the mainloop isn't running at all (see
backend_bases.py:ShowBase). This explains hang-ups when using
interactive mode in a non-shell Python call.

Second, I would be very interested in more information about the
ipython -pylab threading. What do you mean with "running all user
code in a single separate thread"? When it's not the thread importing
Tkinter, the problem persists.

Tkinter is always cumbersome and needs lots of care ... (at least as
soon as the program wants to do something useful :slight_smile:

Also, I cannot see (with reasonable effort) how Threads play a role in
matplotlib. I see there is the Scheduler class in cbook.py, and in
backends/backend_tkagg.py there is "a dict from func-> cbook.Scheduler
threads", but I have no idea how this works. A small hint in the
correct direction would be appreciated! I think it's just a lot
faster although I'm borrowing your time for writing the answer ... I
cannot find any reference to ``.sourced`` in any matplotlib code.
Maybe it's simply dead?

Friedrich

···

On 10/01/2010 09:40 AM, Friedrich Romstedt wrote:

2010/10/2 Eric Firing<efiring@...229...>:

There were several question on the user's list in the recent past
reporting hangs and similar when using TkAgg backend& interactive
mode.

It is known that Tkinter doesn't play well with threading, as long as
one isn't done very carefully.

It could be that matplotlib has implemented it in a way not safe for
Tkinter. This applies if there are Tkinter methods called from
threads other than those which imported Tkinter.

It results in unpredicatable behaviour with exactly the features
reported: Hang-ups, blankening, partial hangup of part of the threads.

Is a rewrite of the Tk interactive code necessary?

I don't see any use of the threading module in backend_tkagg.py or
backend_bases.py. Is that what you are referring to?

Ipython -pylab does use threads (version 0.10), but is intended to avoid
problems by running all user code in a single separate thread.

I just dived a bit into the matplotlib source code, and come up with
partial answers:

When interactive mode is on, the mainloop isn't running at all (see
backend_bases.py:ShowBase). This explains hang-ups when using
interactive mode in a non-shell Python call.

No, I don't think it does. Before going farther, I suggest that you provide specific test cases that fail with mpl from svn. As far as I know, everything works--in or out of interactive mode, in or out of a script, in or out of ipython. There may be problems with some other environments (idle?).

Second, I would be very interested in more information about the
ipython -pylab threading. What do you mean with "running all user
code in a single separate thread"? When it's not the thread importing
Tkinter, the problem persists.

It is the thread importing Tkinter (via the user code), and there is generally no problem.

Tkinter is always cumbersome and needs lots of care ... (at least as
soon as the program wants to do something useful :slight_smile:

Also, I cannot see (with reasonable effort) how Threads play a role in
matplotlib. I see there is the Scheduler class in cbook.py, and in
backends/backend_tkagg.py there is "a dict from func-> cbook.Scheduler
threads", but I have no idea how this works. A small hint in the
correct direction would be appreciated! I think it's just a lot
faster although I'm borrowing your time for writing the answer ... I
cannot find any reference to ``.sourced`` in any matplotlib code.
Maybe it's simply dead?

That's the point--threading does not play any role in mpl by default. It looks like John thought about using cbook.Scheduler in backend_tkagg, but ended up not doing so. Hence Scheduler (and its two subclasses, Timeout and Idle) is just a miscellaneous tool in cbook, available to users, but not used in any backend. Yes, that "sourced" attribute is dead; I have now deleted the associated dead code from svn trunk.

Eric

···

On 10/10/2010 09:49 AM, Friedrich Romstedt wrote:

On 10/01/2010 09:40 AM, Friedrich Romstedt wrote:

Friedrich

Two things to note:

- ipython, even in the 0.10 series, uses threads for the Qt, Gtk and
Wx backends, but *not* for Tk, because python automatically pumps the
Tk event loop when the console blocks on reading (via the C API
PyOSInputHook call). So there is exactly *zero* threading added by
ipython in the specific case of a Tk backend.

- in the 0.11 ipython series, we abandoned threading altogether (it's
just too brittle) and moved to a model similar to the Tk one for *all*
backends, we now use PyOSInputHook with all mpl backends.

hth,

f

···

On Sun, Oct 10, 2010 at 12:49 PM, Friedrich Romstedt <friedrichromstedt@...149...> wrote:

Second, I would be very interested in more information about the
ipython -pylab threading. What do you mean with "running all user
code in a single separate thread"? When it's not the thread importing
Tkinter, the problem persists.

Hello Eric and Fernando,

thank you very much for your answers. It helped :-/ I think I was a
bit too fast here. Eric, you are precisely right, I should have done
more investigation before. I think this issue (my issue) should be
clarified now. I was just alert by the feedback of other users about
hang-ups, I don't know if it was a good idea to bring this to the
list, though. My apologises. Just had too many hidden hang-ups in my
own threaded Tkinter code.

Talking is cheap :-/

Friedrich

2010/10/10 Fernando Perez <fperez.net@...149...>:

Two things to note:

- ipython, even in the 0.10 series, uses threads for the Qt, Gtk and
Wx backends, but *not* for Tk, because python automatically pumps the
Tk event loop when the console blocks on reading (via the C API
PyOSInputHook call). So there is exactly *zero* threading added by
ipython in the specific case of a Tk backend.

This is very interesting, I always asked myself how this works.

···

- in the 0.11 ipython series, we abandoned threading altogether (it's
just too brittle) and moved to a model similar to the Tk one for *all*
backends, we now use PyOSInputHook with all mpl backends.

hth,

f