GnuPlot

Enter gnuplot environment with 'gnuplot' command. In the interactive shell you can use the following commands.

load

To load a command file, which contains other commands for the gnuplot interactive shell. Lines starting with '#' are ignored.

load "plot_data.gp"

You can also directly load it when starting gnuplot, in shell:

gnuplot -persist plot_data.gp

If the file ends with “pause -1”, you can omit the “-persist” argument.

set

  • Axes tics labels.
    set format x "%f"
    set format y "%e"

    Can be used to remove tics labels:

    set format x ""

    For time formats:

    set ydata time
    set timefmt "%M:%S" # input format in data
    set format y "%s"   # outpout format in labels
  • Graph title.
    set title ""
  • Legend position.
    # available: left, right, top, bottom, outside, and below
    set key left bottom
    set key 100,100
  • Automatic legend.
    set key autotitle columnheader
  • Size ratio (-1 to have same scale on x and y axis).
    set size ratio -1   # for plot
    set view equal xyz  # for splot
  • New plot window.
    plot <...>
    set term wxt 1
    plot <...>
    set term wxt 2
    plot <...>
  • Data separator (space by default).
    set datafile separator ","
  • Plot type (histogram)
    set style data histogram
    set style histogram errorbars gap 0 lw 2
    set style fill solid border -1
  • Clear window.
    clear

plot

Plot functions

FIXME

Plot data from a file

  • plot With only one or two columns in the file.
    plot "data.dat"
  • using/u Specifying columns to use. If only one is specified, entry number (line number) is used for x.
    plot "data.dat" using 4
    plot "data.dat" using 4:5
  • every Specifying lines to use (every 2 lines from line 50 to line 1050).
    plot "data.dat" using 4:5 every 2::50::1050
  • separator Set the field separator:
    set datafile separator ","
  • , Several curves in the same plot.
    plot "data1.dat" using 4:5, "data2.dat" using 6:7
    plot \
      "data1.dat" using 4:5, \
      "data2.dat" using 6:7
  • title/t Functions titles.
    plot "data1.dat" using 4:5 title "my curve"
    • Use a variable in title.
      a=2
      plot "data1.dat" using 4:5 title sprintf("curve for a=%.5g",a)
  • rgb Colors.
    show palette colornames
    plot "data1.dat" using 4:5 lt rgb "red"
    plot "data1.dat" using 4:5 lt rgb "#FF0000"
  • palette Colors as value.
    set palette defined (0 "black", 1 "red")
    plot "data1.dat" using 1:2:0 w p palette
  • axes Axes : x1y1 (bottom-left), x2y2 (top-right), x1y2, x2y1.
    plot "data1.dat" using 4:5 axes x1y1, "data2.dat" using 6:7 axes x1y2

    If you want to display different tics on y2 axis, do before the plot command:

    set ytics nomirror
    set y2tics -3.5,0.5,3.5
    # or
    set y2tics auto
  • with Line type.
    # line
    plot "data1.dat" using 4:5 with lines
    # line with custom style
    plot "data1.dat" using 4:5 with lines linestyle 1
    # line with custom line width
    plot "data1.dat" using 4:5 with lines lw 4
    # points
    plot "data1.dat" using 4:5 with points
    # points of custom type
    plot "data1.dat" using 4:5 with points pt 19
    # lines AND points
    plot "data1.dat" using 4:5 with linespoints pt 1
    # labels in addition to points
    plot "data1.dat" using 4:5:1 with labels offset 0.7,0.7
     
    # to find out point types and line width available
    test
  • ($1) Arithmetics on columns data.
    plot "data1.dat" using 4:($5/2+14)
    # where $n means column n
  • (column()) Arithmetics on columns indices.
    plot i=1, "data1.dat" using 1:(column(i+1))
  • fun()= Define variables and functions, use predefined functions (help functions).
    theta=7.72 * (2*pi/360)
    dx=6.7866
    dy=10.1704
    rotation_x(x,y)=(x-dx)*cos(theta)-(y-dy)*sin(theta)
    rotation_y(x,y)=(x-dx)*sin(theta)+(y-dy)*cos(theta)
     
    plot "gps.dat" using (rotation_x($3,$4)):(rotation_y($3,$4))
  • word() Define array variables.
    colors="red blue green"
    print word(colors,3)
  • (?:) Conditions.
    max(x,y)=(x>y?y:x)

    Ignore line under condition:

    use(x)=(x>0?x:0/0)
  • for Plot iteration.
    plot for [file in "run1.dat run2.dat run3.dat"] file using 1:2
    plot for [i=1:3] run.dat using i t sprintf("curve %s", columnheader(i))
    file(n) = sprintf("run_%d.dat",n)
    plot for [i=1:3] file(i) using 1:2
  • fun()=(var= Make operations with different lines using variables assignment in functions.
    • Make sequential operations, the final result is the value of the last operation:
      prev_x=0
      tmp=0
      sum_prev(x)=(tmp=prev_x, prev_x=x, x+tmp)
    • Using cumulated values of a column.
      sum=0
      cumulated(x)=(sum=sum+x, sum)
      plot "idSlamDala.dat" using (cumulated($2)):6
      plot sum=0, "idSlamDala.dat" using (sum=sum+$2,sum):6
    • Subtract the initial value of a column.
      t0=0
      deltat(t)=((t0<=1)?(t0=t,0):(t-t0))
      plot "idSlamDala.dat" using (deltat($1)):2
    • Using difference of two consecutive lines of the same column.
      plot prev=-9999, "idSlamDala.dat" using 1:(dt=(prev==-9999?0/0:$2-prev), prev=$2, dt) 
    • Making an angle continuous.
      k=0
      prev_a=0
      continuous(a)=((prev_a>pi/2&&a<-pi/2 ? k=k+1 : (prev_a<-pi/2&&a>pi/2 ? k=k-1 : k)), prev_a=a, a+k*2*pi)
    • You may also use awk to have a more explicit program, but it won't automatically ignore comment lines:
      plot "< awk '{sum=sum+$2; print sum,$6}' idSlamDala.dat" using 1:2
      plot "< awk 'NR==1 { prev=$2 } NR>1 { dt=$2-prev; prev=$2; print $1,dt; }' idSlamDala.dat" using 1:2
    • Bins mean + eval.
      myplot(x,t) = sprintf("plot \"< awk '\
          NR==1 { i=0; s=0; for(j=0;j<$ARGV_NMEAN;j++) tab[j]=0; } \
          NR>=1 { s=s-tab[i]; tab[i]=\$%d; s=s+tab[i]; i=(i>=($ARGV_NMEAN-1)?0:i+1); } \
          NR>$ARGV_NMEAN { if (i==0) print s/$ARGV_NMEAN; }' $ARGV_FILE\"\
          using 1 t \"%s\"", x, t)
      eval myplot(2, "ax")
    • Sliding mean + continous angle + gunzip.
      plot "< gunzip -c $ARGV_FILE | awk '\
          NR==1 { k=0; prev_a=0; i=0; pi=3.14159265358979 } \
          NR>=1 { a=\$2; k=(prev_a>pi/2 && a<-pi/2 ? k+1 : (prev_a<-pi/2 && a>pi/2 ? k-1 : k)); prev_a=a; a=a+k*2*pi; t=\$1; taba[i]=a; tabt[i]=t; i=(i>=($ARGV_NMEAN-1)?0:i+1); } \
          NR>$ARGV_NMEAN { bias=(a-taba[i])/((t-tabt[i])/3600); print t,bias; }' "\
          using (deltat(\$1)/3600):(\$2*180/pi) with points pt 0 lt rgb "red"  title "bias"
  • paste Plotting one curve with values from different files. Not possible with gnuplot, but paste can help.
    plot "< paste file1.dat file2.dat" using 1:($4-$2)
  • gunzip Use file compressed with gzip. Not possible with gnuplot, but gunzip can help.
    plot "< gunzip -c file.dat" using 1:($4-$2)
    plot "< zcat file.dat" using 1:($4-$2)
    plot "< tar -Oxjf file.dat.tar.bz2" using 1:($4-$2)
  • or anything else with shell commands…
  • fit a function to data:
    f(x) = a*x**2 + b*x + c
    fit f(x) "file.dat" u 1:2 via a,b,c
    plot "file.dat" u 1:2, f(x)
  • sh Passing arguments to a gnuplot script.
    • (preferred method) Putting the gnuplot commands in a shell script (be careful, if you forget a backslash in front of a gnuplot dollar the error message can seem mysterious):
      #!/bin/sh
      ARGV1=$1
      gnuplot << EOF
      plot "$ARGV1" using 1:(\$2*3)
      EOF
      ./plot.gp run.dat

      You can also build a more complicated plot file with multiple steps (for multiplot or multiple curves):

      #!/bin/sh
      ######
      script_header=`cat<<EOF
      set term wxt size 1024,768
      set grid
      plot \
      EOF
      `
      script=$script_header
      ######
      for host in $*; do
      script_loop=`cat<<EOF
          "file_$host.log" u 4:5 w l lt rgb "blue" t "Position $host", \
      EOF
      `
      script="$script$script_loop"
      done
      ######
      script_footer=`cat<<EOF
       
      pause -1
      EOF
      `
      script="$script$script_footer"
       
      gnuplot<<EOF
      $(echo "$script")
      EOF
    • Writing a generic launcher script with environment variables (but difficulty to deal with relative paths):
      #!/bin/sh
      export ARGV1=$2; export ARGV2=$3; export ARGV3=$4; export ARGV4=$5;
      cat $1 | gnuplot
      export -n ARGV1; export -n ARGV2; export -n ARGV3; export -n ARGV4;
      #!gplaunch
      plot "`echo $ARGV1`" using 1:($2*3)
      gplaunch plot.gp run.dat
      ./plot.gp run.dat # if gplaunch is installed on the system
    • Writing a generic launcher script with sed (but difficulty to deal with relative paths):
      #!/bin/sh
      cat $1 | sed "s/\$ARGV1/$2/g" | sed "s/\$ARGV2/$3/g" | sed "s/\$ARGV3/$4/g" | sed "s/\$ARGV4/$5/g" | gnuplot
      #!gplaunch
      plot "$ARGV1" using 1:($2*3)
      gplaunch plot.gp run.dat
      ./plot.gp run.dat # if gplaunch is installed on the system

File outputs

In general be sure that you don't have another “set term” command in your plotting code.

  • EPS and PDF:
    set terminal postscript eps color "Times-Roman" 16
    set output 'plot.eps'
     
    # your plotting code (can be included using the load command)
     
    set output
    !epstopdf --outfile=plot.pdf plot.eps
    quit

    By default, when exporting to ps or pdf, gnuplot changes the lines style with dashes so that they can be recognized when printed in black and white. If you want to keep your lines plain, you can either add the “solid” option to the terminal command, or add the “ls 1” command:

    plot [...] with lines ls 1 lw 2 lt rgb "red"

    Also the grid is black by default, if you want to set it to grey:

    set grid lc rgb "grey"
  • PNG:
    set terminal png size 450,360 small
    set output 'plot.png'
     
    # your plotting code (can be included using the load command)
     
    quit

    If you need dashes but want raster PNG output (eg because the eps would be too large), you can use the eps terminal and convert the file to png at the end with imagemagick:

    set output
    !convert -density 600x600 -background white -flatten plot.eps plot.png
    quit

    When converting eps to png, convert creates a png with non visible alpha data even if flatten, and some viewers like evince fail to antialias them. So you have to convert it twice:

    set output
    !convert -density 600x600 -background white -flatten plot.eps ppm:- | convert - plot.png
    quit
  • SVG:
    set terminal svg rounded size 450,360
    set output 'plot.svg'
     
    # your plotting code (can be included using the load command)
     
    set output
    !gzip -S z plot.svg
    quit
  • Conditional output:
    #!/bin/sh
     
    TITLE=plot
    if [[ $1 == "pdf" ]]; then
        GTERM='set terminal postscript eps color "Times-Roman" 16 solid size 5,2.9 ; set output "$TITLE.eps"'
        OUTPUT='!epstopdf --outfile=$TITLE.pdf $TITLE.eps'
        GRIDCOLOR='lc rgb "grey"'
        shift
    elif [[ $1 == "png" ]]; then
        GTERM='set terminal pngcairo font "Times,32" size 1830,1780 ; set output "$TITLE.png"'
        OUTPUT=''
        GRIDCOLOR=''
        shift
    else
        GTERM='set term wxt size 1024,768'
        OUTPUT=''
        GRIDCOLOR=''
    fi
     
    gnuplot -persist << EOF
     
    $GTERM
    set grid $GRIDCOLOR
     
    # your plotting code (can be included using the load command)
     
    set output
        $OUTPUT
     
    EOF

Interactivity

  • Keyboard bindings
    bind "a" "plot x*x"
  • Progressive display (but the plot is not interactive anymore)
    plot "file.dat" u 1
    while(1) { replot ; pause 0.2 }
  • Pausing and resuming the progressive display for interactivity (only works with x11 terminal if started in interactive gnuplot shell… for wxt terminal the event processing loop – wxt_gui.cpp:wxt_waitforinput function – is not called during the update loop, but ctrl-c in the shell stops the update loop and allows plot interactivity afterwards, contrary to x11 term…).
    set terminal x11
    bind "c" "update=1-update ; while(update) { replot ; pause 0.1 }"
    plot "file.dat" u 1
    update=1
    while(update) { replot ; pause 0.2 }

Example

This is a typical example that uses the most useful features to plot data from a file. It is easy to copy and adapt for your own use.

set term wxt size 1024,768
 
# file to plot:
file="rtslam.log"
 
# to have smaller crosses:
set pointsize 0.3333333333333
 
# to have the same scale along x and y axis:
#set size ratio -1
 
# to display a grid:
#set grid
 
# to have a different right y axis:
set y2tics auto
set ytics nomirror
 
# titles
set title "Accelerometer biases and g estimation"
set xlabel "Time (s)"
set ylabel "Acceleration (m/s2)"
set y2label "Angle (deg)"
 
# to define some functions:
norm3(x,y,z)=sqrt(x*x+y*y+z*z)
pitch(x,y,z) = atan2(-x, z)*180/pi
roll(x,y,z) = atan2(y, z)*180/pi
 
# to define some variables:
t0=1281469302
 
# now plot:
plot \
    file using ($1-t0):15 with points pt 1 lt rgb "red"       title "Bias AX", \
    file using ($1-t0):16 with points pt 1 lt rgb "dark-red"  title "Bias AY", \
    file using ($1-t0):17 with points pt 1 lt rgb "orange"    title "Bias AZ", \
    file using ($1-t0):(norm3($21,$22,$23)/100)           with points pt 1 lt rgb "blue"       title "Norm g / 100", \
    file using ($1-t0):(pitch($21,$22,$23))     axes x1y2 with points pt 1 lt rgb "green"      title "Pitch g", \
    file using ($1-t0):(roll($21,$22,$23))      axes x1y2 with points pt 1 lt rgb "dark-green" title "Roll g"
 
 
# prevent window from closing at the end
pause -1
software/gnuplot.txt · Last modified: 2024/04/19 09:54 by cyril
CC Attribution-Share Alike 4.0 International
Driven by DokuWiki Recent changes RSS feed Valid CSS Valid XHTML 1.0