Version 24 of gnuplot

Updated 2015-07-02 08:46:48 by APN
What: gnuplot
Where: http://www.gnuplot.info/
http://gnuplot.sf.net/
http://sf.net/projects/gnuplot/
ftp://ftp.gnuplot.vt.edu/pub/gnuplot/
Description: Gnuplot is a command-line driven interactive function plotting utility for UNIX, MSDOS, VMS, and many other platforms.
Updated: 12/2002
Contact: See web site

People often ask about combinations of gnuplot [L1 ] and Tcl; in fact, archives from comp.lang.tcl pertaining to gnuplot are quite extensive [L2 ]. Perhaps the most impressive marriage of the two is UniGNUPlot [L3 ], which makes for quick development of useful graphs:

"Just with simple 'click' and scroll bars, you have a good graphic in seconds, ready to insert in the document what you want or directly to the printer..."

gnuplot handles real and complex data. plotting specific columns i.e "using 1:3" or computations i.e "using ($1-$2):(abs($3) - pow($5,2))" from composite data is rather easy. Aside from plotting datasets gnuplot can handle functions i.e. f(x) = ax + bx² .. . As an encore gnuplot can fit functions to given data.


See also 3D animation on canvas with Gnuplot, unignuplot


AMW 2012-Apr-13

The following proc will allow executing gnuplot from a Tcl script. I use it in interactive sessions in Tkcon to plot data collected by other commands.

#-------------------------------------------------------------------------------
#  gp                        gnuplot
#  start and control gnuplot
#  Normally, all args are passed to gnuplot.
#  The following convenience function is applied: if the first argument is a
#  filename OR if the first argument is the command 'plot', then
#  - if filename contains wildcards (*), the youngest matching file is
#        selected
#  - the selected file is searched for lines containing "#! command"
#     - if such commands are found, these commands are sent to gnuplot
#     - otherwise, a plot command is sent to gnuplot
#-------------------------------------------------------------------------------
#  Examples:
#  gp filename            \   if filename contains wildcards (*),
#  gp 'filename'           \      select youngest file matching
#  gp plot filename        /  if file exists, try to read "#! commands"
#  gp plot 'filename'     /       from it
#  gp filename using 3:6  ->  plot 'filename' using 3:6
#  gp set title 'TEST'
#  gp replot
#  gp exit                ->  terminate gnuplot
#-------------------------------------------------------------------------------
proc gp { args } {
    global gnuplot gnuplot_rx

    set cmdline ""

    set argc [llength $args]

    set tryDaq         0
    if { $argc >= 2 && [lindex $args 0] == "plot" } {
        set tryDaq 1
    }

    #-----------------------------------------------------------------
    #  try to interpret arg as a filename
    #-----------------------------------------------------------------
    set filename [string trim [lindex $args $tryDaq] "'"]

    #-----------------------------------------------------------------
    #  convenience: if filename contains '*', look for youngest
    #        file matching pattern
    #-----------------------------------------------------------------
    if { [regexp {\*} $filename] } {
        set dir   [file dirname $filename]
        set mask  [file tail $filename]
        set files [glob -nocomplain -directory $dir -types f $mask]
        if { [llength $files] > 0 } {
            set filename [lindex $files 0]
            set filetime [file mtime $filename]
            foreach fname [lrange $files 1 end] {
                set mtime [file mtime $fname]
                if { $mtime > $filetime } {
                    set filename $fname
                    set filetime $mtime
                }
            }
        }
    }

    #-----------------------------------------------------------------
    #  check if arg is a filename, try to read "#! commands" from file
    #-----------------------------------------------------------------
    if { [file exist $filename] } {
        if { $argc <= 2 } {
            set f [open $filename "r"]
            while { [gets $f line] > -1 } {
                if { [regexp {^#!\s*(.*)} $line all cmd] } {         ;#
                    append cmdline "$cmd\n"
                }
            }
            close $f
            regsub -all {\$this} $cmdline $filename cmdline
        }
        if { $cmdline == "" } {
            set cmdline "plot '$filename'"
        }

        set cmdline "set title '$filename'\n$cmdline"
        foreach arg [lrange $args $tryDaq+1 end] { append cmdline "$arg " }
    }

    #-----------------------------------------------------------------
    #  build cmdline from args
    #-----------------------------------------------------------------
    if { $cmdline == "" } {
        foreach arg $args { append cmdline "$arg " }
    }

    #-----------------------------------------------------------------
    #  start gnuplot if not alread running
    #-----------------------------------------------------------------
    if { ! [info exist gnuplot] } {
        set gpexe "gnuplot"
        # gnuplot writes to stderr!
        set gnuplot [open "|$gpexe 2>@1" r+]
        fconfigure $gnuplot -buffering none
        fileevent  $gnuplot readable {
            #---------------------------------------------------------
            # async. background receive
            #---------------------------------------------------------
            if { [eof $gnuplot] } {
                puts stderr "# close gnuplot $gnuplot"
                close $gnuplot
                unset gnuplot
            } else {
                set rx [gets $gnuplot]
                if { $gnuplot_rx == "-" } {
                    puts stderr $rx        ;# 'gp' no longer waiting

                } else {
                    set gnuplot_rx $rx
                }
            }
        }
    }

    #-------------------------------------------------------------------
    #  send command to gnuplot
    #-------------------------------------------------------------------
    puts "gnuplot> $cmdline"
    set gnuplot_rx ""
    puts $gnuplot "$cmdline\n"

    #-------------------------------------------------------------------
    #  wait 100ms if gnuplot writes a response
    #-------------------------------------------------------------------
    after 100 [list append gnuplot_rx ""]
    vwait gnuplot_rx
    set rx $gnuplot_rx
    set gnuplot_rx "-"        ;# show I'm not waiting any longer!
    return $rx
}

Also see Ukaz: A graph widget written in pure Tcl/Tk.

This is a package which provides a widget to plot data in x-y format for scientific applications. It sets reasonable defaults to display most datasets without the need for individual settings. Ukaž was designed to be easy to use and borrows most of the syntax from the popular gnuplot package, slightly adapted to be more Tcl friendly.