ruby, gnuplot, x11

Discussion in 'Ruby' started by Joel VanderWerf, Mar 4, 2008.

  1. This is a workaround for a minor annoyance in driving gnuplot from ruby
    (or from anything else for that matter), and I'm posting it here for
    posterity. Hope it helps someone. Sorry if it's a bit OT...

    The scenario is this: you're developing a tool that sometimes pops up a
    graph window (or three) for the user to look at and close when desired.
    You'd like that window to stay alive until the user closes it
    (preferably, even if the main tool itself has exited). When the user
    closes it, you'd like to clean up the processes that manage it.

    The problem is this: there's no way in gnuplot to detect that the user
    has closed the window (using 'q' or the close box), so cleanup becomes
    problematic. You either time out the child process arbitrarily (yuck) or
    use the "-persist" option (which disables mouse interaction), or just
    leave those processes running (which may keep tempfiles around, too).
    (See 7.9 of the Gnuplot FAQ.) Not good alternatives. The last of the
    three is used in the first part of my example below.

    (I don't think the ruby-gnuplot gem solves this problem.)

    Anyway, here's my X11 solution. It works by managing the window title
    and the periodically querying the X server to see if that title is still
    around. Windows or OSX will have to be handled differently, probably.

    ------- gp-x11-prob.rb -------

    # This solves the problem on xwindows in which closing a gnuplot
    # window doesn't exit the controlling process, and so you end up
    # with lots of idle gnuplot processes, which have to be killed
    # manually. The problem can be seen in the following simplistic
    # attempt to spawn a process to manage a gnuplot session. It works
    # as far as setting up a process that keeps gnuplot alive.
    # However, gnuplot has no way of notifying the controlling process
    # that the window has been closed by the user either using the "q"
    # key or clicking in the close box. As long as the pipe remains
    # open, gnuplot awaits more commands (as it should), but we cannot
    # close the pipe because we don't know the user is done with the
    # session. This is more of an issue for tools that wrap gnuplot
    # rather than for direct command line use. A long-living gui can
    # easily spawn hundreds of these processes.
    #
    # The 'gnuplot -persist' option also solves this process problem
    # but is not very useful because it disables mouse interaction.
    #
    # Run like this to see the problem:
    #
    # ruby gp-x11-prob.rb bad
    #
    # Then close the window. To stop the gnuplot processes you will
    # have to kill the gnuplot process.
    #
    # Run like this to use the workaround
    #
    # ruby gp-x11-prob.rb
    #
    # Within 5 sec after closing the window, the gnuplot process
    # is gone!
    #
    # ps -f | grep gnuplot
    #

    if ARGV[0] == "bad"
    fork do
    trap "CLD" do exit end
    # doesn't normally happen, even on "q" keypress or window
    # close event so this isn't a way to tell that user has
    # finished and we can close pipe

    gp = IO.popen("gnuplot", "w")
    gp.sync = true
    gp.puts "plot '-' w l\n1 2\n3 4\ne\n"
    # inline data, but could just as well be file

    sleep
    end
    exit
    end

    # The workaround uses xwindows tools to check whether the plot
    # window has been closed. This assumes that assume fork works (so,
    # not win32), and that we're on X windows and we have xprop (or
    # xwininfo) program (so, not OSX native GUI)

    fork do
    gnuplot_counter = 0

    gp = IO.popen("gnuplot", "w")
    gp.sync = true

    uniqname = "Gnuplot_#{Process.pid}_#{gnuplot_counter+=1}"
    gp.puts "set term x11 title #{uniqname}"
    gp.puts "plot '-' w l\n1 2\n3 4\ne\n"

    loop do
    sleep 5
    rslt = system(
    "xprop -name #{uniqname} WM_STATE 1>/dev/null 2>/dev/null")
    break unless rslt
    end
    end


    --
    vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407
    Joel VanderWerf, Mar 4, 2008
    #1
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Greg
    Replies:
    2
    Views:
    3,045
    Marco Schmidt
    Jul 21, 2003
  2. Nebojsa Topolscak
    Replies:
    3
    Views:
    551
    Jon Caldwell
    Jan 14, 2005
  3. Robert Holt

    Getting X11 window id

    Robert Holt, Oct 16, 2005, in forum: Java
    Replies:
    5
    Views:
    2,546
    Robert Holt
    Oct 18, 2005
  4. Malte Milatz

    Ruby/X11

    Malte Milatz, Feb 27, 2005, in forum: Ruby
    Replies:
    3
    Views:
    161
    Eric Hodel
    Feb 28, 2005
  5. saLOUt
    Replies:
    1
    Views:
    79
    Joel VanderWerf
    Feb 9, 2010
Loading...

Share This Page