views:

30

answers:

1

I've got a script which creates a graph, but the script keeps running in the background until the window is closed. I'd like it to quit as soon as the window is created, so that Ctrl-C in the shell won't kill the window, and so that the user can leave the window open and continue working in the shell without bg-ing it manually. I've seen some solutions with daemons, but I'd like to avoid splitting this into two scripts. Is multiprocessing the easiest solution, or is there something shorter?

The relevant show() command is the last thing that is executed by the script, so I don't need to keep a reference to the window in any way.

Edit: I don't want to save the figure as a file, I want to be able to use the interactive window. Essentially the same as running mian ... & in bash

+1  A: 

This works for Unix:

import pylab
import numpy as np
import multiprocessing as mp
import os

def display():
    os.setsid()
    pylab.show()

mu, sigma = 2, 0.5
v = np.random.normal(mu,sigma,10000)
(n, bins) = np.histogram(v, bins=50, normed=True)
pylab.plot(bins[:-1], n)
p=mp.Process(target=display)
p.start()

When you run this script (from a terminal) the pylab plot is displayed. Pressing Ctrl-C kills the main script, but the plot remains.

unutbu
I tried this with `if __name__ == '__main__':\n process = Process(target = main)\n process.start()`, but no luck. It doesn't display anything, and when I press Ctrl-C it interrupts both processes.
l0b0
Are you using Windows?
unutbu
Nope, unutbu, Ubuntu :)
l0b0
@l0b0: Did you try my script exactly the way it is? It should work on Ubuntu without modification. In your comment above, are you really using `target = main`? It should be `target=display`.
unutbu
When running your script using `python test.py`, it just halts. Never gets anywhere. When running `./test.py` I get a strange "cross" cursor, which saves a screenshot of the window I click on on the desktop as a file called "pylab". Copying the script into a python shell produces nothing except for the pylab.plot line which returns "[<matplotlib.lines.Line2D object at 0x9d59c2c>]". It **only** works in `ipython -pylab`. And when using this method in my own script (http://github.com/l0b0/mian/blob/master/mian/mian.py), nothing happens (Debug output is produced, but no GUI).
l0b0
@l0b0: Do you use `matplotlib` in other scripts? Does it work for you? It sounds like you haven't configured `~/.matplotlib/matplotlibrc`. Perhaps open that file and see what `backend` is set to. I think the default might be `backend : Cairo`, which produces the results you describe. I set mine to `backend : GtkAgg`. If that doesn't work, there is also GTK GTKAgg GTKCairo CocoaAgg FltkAgg MacOSX QtAgg Qt4Agg TkAgg WX WXAgg Agg Cairo GDK PS PDF SVG Template. Experiment with them until you find one that works.
unutbu
matplotlib works just fine. The only thing the existing script is missing is some way to detach the process of the resulting window from the shell script.
l0b0
@l0b0: The `os.setsid()` command, when issued in the subprocess spawned by `mp.Process`, should be all you need to detach the subprocess from the main process. I'm not sure why the script I posted above works for me but not for you.
unutbu
The backend could really make a difference, as unutbu noted.
Jouni K. Seppänen