Importing pyplot blocks input thread

I am trying to write some code that uses an input thread to check for user
input while another thread is running some calculations (see example below).
What I have noticed is that just including an import of pyplot (regardless
of whether it is used by the code or not) causes the call to raw_input in
the input thread to block the main thread. It works fine when I don't
import pyplot. Importing pyplot is a consequence of other libraries that I
need to use in the code, so I would like to find a way to make this work.

I have python 2.7.3, matplotlib 1.2.0, and am currently using the GTKAgg
backend. Any help is much appreciated.

Here is the example code:

import time
import threading
import matplotlib.pyplot # Works fine if this is commented out

def input_thread():
    raw_input('Press a key:')
    print "Input data received"

thread = threading.Thread(target=input_thread)
thread.start()
time.sleep(.01)
print

# Main thread (e.g. a calculation that can take some time)
for i in xrange(10):
    print i
    time.sleep(.5)

···

--
View this message in context: http://matplotlib.1069221.n5.nabble.com/Importing-pyplot-blocks-input-thread-tp41731.html
Sent from the matplotlib - users mailing list archive at Nabble.com.

I am trying to write some code that uses an input thread to check for user
input while another thread is running some calculations (see example below).
What I have noticed is that just including an import of pyplot (regardless
of whether it is used by the code or not) causes the call to raw_input in
the input thread to block the main thread. It works fine when I don't
import pyplot. Importing pyplot is a consequence of other libraries that I
need to use in the code, so I would like to find a way to make this work.

I have python 2.7.3, matplotlib 1.2.0, and am currently using the GTKAgg
backend. Any help is much appreciated.

Here is the example code:

import time
import threading

Before the *first* import of pyplot, you need to have:

import matplotlib
matplotlib.use("agg")

or specify any other non-interactive backend. Alternatively, you can specify the backend in a matplotlibrc file.

This assumes you don't actually need an interactive backend. If you do need it, then I suspect you will need to change the strategy you are using in your program, ideally eliminating the input thread. You might use a gtk idle event callback to handle the user input, for example. The problem here is that python threads and gui toolkits tend not to mix well.

I suspect that raw_input is using the PyOS_InputHook, which is also being used by gtk, so you are violating the prohibition against gui-related activities being in more than one thread.

Eric

···

On 2013/08/06 10:08 AM, John McFarland wrote:

import matplotlib.pyplot # Works fine if this is commented out

def input_thread():
     raw_input('Press a key:')
     print "Input data received"

thread = threading.Thread(target=input_thread)
thread.start()
time.sleep(.01)
print

# Main thread (e.g. a calculation that can take some time)
for i in xrange(10):
     print i
     time.sleep(.5)

--
View this message in context: http://matplotlib.1069221.n5.nabble.com/Importing-pyplot-blocks-input-thread-tp41731.html
Sent from the matplotlib - users mailing list archive at Nabble.com.

------------------------------------------------------------------------------
Get 100% visibility into Java/.NET code with AppDynamics Lite!
It's a free troubleshooting tool designed for production.
Get down to code-level detail for bottlenecks, with <2% overhead.
Download for free and get started troubleshooting in minutes.
http://pubads.g.doubleclick.net/gampad/clk?id=48897031&iu=/4140/ostg.clktrk
_______________________________________________
Matplotlib-users mailing list
Matplotlib-users@lists.sourceforge.net
matplotlib-users List Signup and Options

Thanks Eric, that did work for me. I don’t necessarily need an
interactive backend for this, but it could be nice to get it to work. I
just tried switching raw_input to sys.stdin.readline, and that seems to
work even with the interactive backend.

John

···

On 8/6/2013 3:31 PM, Eric Firing [via matplotlib] wrote:

Before the first import of pyplot, you need to have:

import matplotlib

matplotlib.use(“agg”)

or specify any other non-interactive backend. Alternatively, you can

specify the backend in a matplotlibrc file.

This assumes you don’t actually need an interactive backend. If you do

need it, then I suspect you will need to change the strategy you are

using in your program, ideally eliminating the input thread. You might

use a gtk idle event callback to handle the user input, for example.

The problem here is that python threads and gui toolkits tend not to mix

well.

I suspect that raw_input is using the PyOS_InputHook, which is also

being used by gtk, so you are violating the prohibition against

gui-related activities being in more than one thread.

Eric


View this message in context: Re: Importing pyplot blocks input thread

Sent from the matplotlib - users mailing list archive at Nabble.com.