Using perl open2 to pipe data through gnuplot

open2 is useful for piping through some program, and back. This is handy in many situations - personally I find it handy for turning database tables into graphs with gnuplot .

You want to use open2 when you're doing something like this;

  1. You have a program which takes something on it's standard input, and changes into something on standard output. The simplest example of such a program is something like sort, though, in my example, I've used gnuplot .
  2. You have a bunch of stuff you want to feed to the program.
  3. In return, you want to get a whole bunch of stuff, after having being passed through the program

The following example takes an array and generates a PNG graph directly from it, using gnuplot. I've omitted code to check for sanity (For example, checking that $xArray and $yArray are the same length). You should also check out this book if you want more detailed perl examples.

 
        use IPC::Open2;
        print "Content-type:image/png\n\n";  

# Many examples for open2 don't include creation of the filehandles.
# You aren't meant to pass them in without creating them first!
        local (*READ, *WRITE);                                                                      
        my $pid = open2(\*READ, \*WRITE, "gnuplot" );                                                                                                                                                                   

# We could have also done it like this 
# my ($readFH, $writeFH); 
# my $pid     = open2($readFH, $writeFH, "gnuplot");                                                                                                                  

                                                                                                                   
        print WRITE "set terminal png small\n";                                                                    
        print WRITE "set nokey\n";                                                                                 
        print WRITE "set grid\n";                                                                                  
        print WRITE "set size 0.5, 0.5\n";                                                                       
        print WRITE "set data style points\n";                                                                     
                                       
        print WRITE "set title \'$title\'\n";                                                                      
        print WRITE "set xlabel \'$xLabel\'\n";                                                                    
        print WRITE "set ylabel \'$yLabel\'\n";                                                                    
        print WRITE "plot \'-'\n";                                                                                 
                                                                                                                   
        foreach my $index (0..$#xArray)                                                                            
                {                                                                                                  
                print WRITE "$xArray[$index]\t$yArray[$index]\n";                                                  
                }                                                                                                  
                                                                                                                   
        close(WRITE);                                                                                              
        my @data = <READ> ;                                                                                         
        print join ("", @data); 

Important note!

There are three important things to remember when using open2 . They are (listed in order of importance):
  1. open2 does not play well with mod_perl.
  2. open2 does not play well with mod_perl.
  3. open2 does not play well with mod_perl.
Please let me know if you find out why that is.