Using Gnuplot

Gnuplot is a very powerful plotting program that can generate publication-quality images and plots. It creates both 2-dimensional plots and 3-dimensional surface plots. It works with basic text files with, as far as I know, whitespace-delimited numbers.

Furthermore, gnuplot works with a number of different file formats for outputting graphs, including GIF, JPEG, and PNG images, as well as more LaTeX-friendly formats like postscript and encapsulated postscript.

I tried to lay this out to satisfy two different goals. First, I wanted it to be useful as a step-by-step tutorial to ease would-be users into using gnuplot, and second, I wanted it to serve as a useful reference (particularly to myself, most likely), which is why I would expect the Table of Contents to be rather large.

Why gnuplot?

You may ask, why pick gnuplot over some of the other plotting alternatives like Excel (or some other spreadsheet), origin, matplotlib, etc.? I'll try to list some of the reasons I can think of, starting with the most important:

  1. It is scriptable — that is, you can spend a little bit of time getting your graph to look just the way you want it, then you have a script that will work for whatever data sets you have. Instantly. You only have to spend the time formatting a single graph, and all other similar ones can be created instantly (and identically) from that template
  2. It has an expansive built-in help function to help you every step of the way
  3. It can print to an almost limitless number of file formats (terminals), so the terminal you want is almost certainly available
  4. It is incredibly flexible, giving you control over almost every aspect of your graph
  5. Once you become comfortable with gnuplot, it is fast and easy to create customizable plots (especially once you've built up an army of scripts)
  6. The learning curve isn't nearly as steep as you'd think with it being a command-line-only interface
  7. It's widely used, so there are many, many tutorials and references around for gnuplot (including this one).
  8. It's free! Though not actually associated with the GNU project or the FSF (Free Software Foundation). It's license is slightly more restrictive, not allowing you to actually distribute your own modified versions of gnuplot — though you can distribute patches to modify certain versions.

Setting up Fonts

If you want to expand the fonts that gnuplot knows about when printing image files (like GIF, PNG, JPG, etc.), you need to set the GDFONTPATH environment variable to point to directories that contain font files.

For Mac OS X, this is typically

export GDFONTPATH=/Users/<your_username>/Library/Fonts

Using Cygwin on the PC, a typical choice is

export GDFONTPATH=/cygdrive/c/Windows/Fonts

On Linux, I typically keep a .fonts folder in my home directory with all of my fonts in it, so I would set

export GDFONTPATH=$HOME/.fonts

Running GNUPLOT and Getting Help

You can run gnuplot straight from a terminal (command-line) using the command gnuplot. If it is available, you should see something like

bash$ gnuplot

    G N U P L O T
    Version 4.2 patchlevel 6 
    last modified Sep 2009
    System: Linux 2.6.32-36-generic

    Copyright (C) 1986 - 1993, 1998, 2004, 2007 - 2009
    Thomas Williams, Colin Kelley and many others

    Type `help` to access the on-line reference manual.
    The gnuplot FAQ is available from http://www.gnuplot.info/faq/

    Send bug reports and suggestions to <http://sourceforge.net/projects/gnuplot>

Terminal type set to 'wxt'
gnuplot>

(The terminal may be set to "aqua" on a Mac or "x11" on many other platforms.) This is the main interface to Gnuplot. You can use the help command to get interactive help while inside the gnuplot interpreter. You can specify a command to get more pointed help, too.

gnuplot> help plot
 `plot` is the primary command for drawing plots with `gnuplot`.  It creates
 plots of functions and data in many, many ways.  `plot` is used to draw 2-d
 functions and data; `splot` draws 2-d projections of 3-d surfaces and data.
 `plot` and `splot` contain many common features; see `splot` for differences.
 Note specifically that although the `binary <binary list>` variation does
 work for both `plot` and `splot`, there are small differences between these
 modes.  Furthermore, `plot`'s `axes` option does not exist for `splot`.

 Syntax:
       plot {<ranges>}
            {<function> | {"<datafile>" {datafile-modifiers}}}
            {axes <axes>} {<title-spec>} {with <style>}
            {, {definitions,} <function> ...}

 where either a <function> or the name of a data file enclosed in quotes is
 supplied.  A function is a mathematical expression or a pair of mathematical
 expressions in parametric mode.  The expressions may be defined completely or
 in part earlier in the stream of `gnuplot` commands (see `user-defined`).

 It is also possible to define functions and parameters on the `plot` command
 itself.  This is done merely by isolating them from other items with commas.

Press return for more:

etc.

Executing Basic Shell Commands in GNUPLOT

Sometimes you may find yourself wishing you could run a shell command while inside gnuplot. Say, for instance, you forgot the name of the data file you wanted to plot, etc.)

You can execute some shell commands (like ls), using the ! operator first. For instance

gnuplot> !ls
a.out  nctest.f90  test.csv  test_debug.f90  test.py
!
gnuplot>

You can also change directories using cd "directory_name"

Gnuplot Command Shortcuts

A very helpful thing to know before going too far is that gnuplot is very clever about recognizing shortcuts as you become more advanced. Commands only need to be typed out enough to make them uniquely identifiable by the interpreter. For instance, because the quit command is the only command that starts with "q" in gnuplot, any of the commands (q, qu, qui, or quit) will trigger that action.

Likewise, the lines

plot 'datafile' with lines

and

plot 'datafile' w l

are equivalent.

Functions

This section deals with generating mathematical functions, like

(1)
\begin{equation} f(x) = 3x^2+2x+1 \end{equation}

Functions are very useful because you can plot them, fit data to them, and modify data using them. You can define a function via the following syntax:

gnuplot> f(x) = 3*x**2 + 2*x + 1
gnuplot>

All 1-D functions should take x as its argument if you intend to plot them. If you plot a parametric equation, both variables should be functions of t. For instance

gnuplot> f(t) = 1
gnuplot> g(t) = t
gnuplot>

plots a straight, vertical line if plotted as plot f(t), g(t), and a straight horizontal line if plotted as plot g(t),f(t)

All 2-D equations take x,y as arguments if you plan to plot those. Additionally, you may define variables as coefficients. That is,

(2)
\begin{equation} f(x) = a x^2 + b x + c \end{equation}

has three variable coefficients that are not arguments to the function. You can assign values to these variables at any point (and change them whenever you want to), or you can use them to fit to data. Assign a variable just like you assign an equation — with an equals sign.

gnuplot> a = 10
gnuplot>

List of operators and functions gnuplot knows about

I omit here the operators that are obvious, like +, -, /, and *.

**
exponential operator (a ** b is a raised to the power of b)
log
natural logarithm
log10
logarithm base 10
sin, cos, tan
normal trig functions sine, cosine, tangent
sinh, cosh, tanh
hyperbolic trig functions
asin, acos, atan
arc-trig functions
asinh, acosh, atanh
arc-hyperbolic trig functions
gamma
gamma function
erfc
complementary error function
erf
error function
ceil
ceiling function (smallest integer greater than or equal to value)
floor
floor function (largest integer less than or equal to value)

Very Basic Plotting (and Replot) in gnuplot

This section deals with creating plots in gnuplot. You plot data by using the plot command. The replot command will re-run the last plot command, but also takes the same arguments that plot takes. Thus, you can either plot 2 items in the same plot command via

gnuplot> plot 'datafile', f(x)

or you can do it in two steps via

gnuplot> plot 'datafile'
gnuplot> replot f(x)

Each plot command will completely erase any plot command(s) that came before it.

Plotting functions

You can plot functions in one of two ways. To plot "normal" functions of a single variable, the independent variable should always be x. For instance:

gnuplot> plot 3*x**2+2*x+1
gnuplot>

and

gnuplot> f(x) = 3*x**2+2*x+1
gnuplot> plot f(x)
gnuplot>

both plot equation (1) above, and should show a figure like this:

gnuplot_plot_function.jpg

Plotting data

As an example, take the data from the attached file here (the first section is shown below)

   0.0000000000000000       1.63187922851102197E-043
  4.00801603206412792E-003  4.08358169487598205E-043
  8.01603206412825585E-003  8.57322405816442756E-043
  1.20240480961923846E-002  1.73129936161289217E-042
  1.60320641282565117E-002  3.45784071201136770E-042
  2.00400801603206405E-002  6.87578404252221707E-042
  2.40480961923847693E-002  1.36344497652106874E-041
  2.80561122244488981E-002  2.69730486896935522E-041
  3.20641282565130234E-002  5.32407665559785807E-041
  3.60721442885771557E-002  1.04855536367650238E-040
  4.00801603206412810E-002  2.06050467205319491E-040
  4.40881763527054132E-002  4.04009138612405269E-040
  4.80961923847695386E-002  7.90394184633720358E-040
  5.21042084168336639E-002  1.54287490021283476E-039
  5.61122244488977961E-002  3.00504895188511843E-039
  6.01202404809619215E-002  5.83990342350223851E-039
  6.41282565130260468E-002  1.13238072759041723E-038
  6.81362725450901791E-002  2.19084359508190369E-038
  7.21442885771543113E-002  4.22923471384300249E-038
...

We can plot this data in one of 3 ways. We can plot just the points:

gnuplot> plot 'plot_data_1.txt' with points
gnuplot>
plot1_with_points.jpg

with just lines connecting the points

gnuplot> plot 'plot_data_1.txt' with lines
gnuplot>
plot1_with_lines.jpg

or with points and lines connecting the points

gnuplot> plot 'plot_data_1.txt' with linespoints
gnuplot>
plot1_with_linespoints.jpg

Making Plots Pretty

Selecting a Terminal

One thing that can affect how your plot looks is which terminal (what image library you choose to use to display your plot) you use and how you set that terminal up. You can get a full list of available terminals by using the command set terminal

gnuplot> set terminal

Available terminal types:
           aed512  AED 512 Terminal
           aed767  AED 767 Terminal
             aifm  Adobe Illustrator 3.0 Format
         bitgraph  BBN Bitgraph Terminal
              cgm  Computer Graphics Metafile
            corel  EPS format for CorelDRAW
             dumb  ascii art for anything that prints text
              dxf  dxf-file for AutoCad (default size 120x80)
            eepic  EEPIC -- extended LaTeX picture environment
              emf  Enhanced Metafile format
            emtex  LaTeX picture environment with emTeX specials
         epslatex  LaTeX picture environment using graphicx package
     epson_180dpi  Epson LQ-style 180-dot per inch (24 pin) printers
      epson_60dpi  Epson-style 60-dot per inch printers
      epson_lx800  Epson LX-800, Star NL-10, NX-1000, PROPRINTER ...
              fig  FIG graphics language for XFIG graphics editor
              gif  GIF images using libgd and TrueType fonts
             gpic  GPIC -- Produce graphs in groff using the gpic preprocessor
          hp2623A  HP2623A and maybe others
           hp2648  HP2648 and HP2647
           hp500c  HP DeskJet 500c, [75 100 150 300] [rle tiff]
Press return for more:
  • On MacOS X, aqua is a good terminal to use (and is default if you install gnuplot from MacPorts). You can also save aqua plots as PDF files directly in the aqua application window.
  • On Ubuntu, wxt is a nice-looking terminal with several options.
  • On other systems where these may not be available, x11 is a good default terminal.
  • To save images, you can use any of the image file formats (gif, jpeg, png), or you can use a postscript or encapsulated postscript (some gnuplot installations have variants specific for LaTeX).

Terminal properties

The main way you can adjust the look of your plot is not which terminal you choose, but the options that you choose to customize it. You can specify the default text, text size, and graph size. For instance, look at how the selection of terminal below affects the appearance of the plotted data with points (second image on this page):

gnuplot> set terminal gif font 'calibri,20' size 800,600 enhanced
Terminal type set to 'gif'
Options are 'nocrop enhanced font calibri 20 size 800,600 '
gnuplot> set output 'plot_1_gifterm.gif'
gnuplot> plot 'plot_data_1.txt' with points
gnuplot> quit
plot_1_gifterm.gif

I will describe the bits of the command set terminal gif font 'calibri,20' size 800,600 enhanced:

  • set terminal gif : This command sets the terminal to the gif image format
  • font 'calibri,20' : This sets the default font to be of type "calibri" with a font size of 20 pt.
  • size 800,600 : This sets the size of the image to be 800 pixels by 600 pixels
  • enhanced : This keyword allows some more advanced formatting. For instance, the string "x^2" will be expanded wherever it is displayed in the terminal as x2 and "pK_a" will be displayed as pKa. We will see this effect when we do some examples below with applying labels.

Titles and Axis labels

Good plots should have titles and labels for all of the axes. You can specify the font type and size to override the terminal defaults for each of these if you want. In this way, you can create plots that have a large title, smaller axis labels, and an even smaller legend/tic mark labels.

The title is set via set title

The x-axis label is set via set xlabel

The y-axis label is set via set ylabel

Look at the effect that the below code has on our last GIF image.

gnuplot> set terminal gif font 'calibri,12' size 800,600 enhanced
Terminal type set to 'gif'
Options are 'nocrop enhanced font calibri 12 size 800,600 '
gnuplot> set output 'plot_1_titled_gifterm.gif'
gnuplot> set title 'A Data File Plotted With Points' font 'calibri,25'
gnuplot> set xlabel 'Domain_{independent variable}' font 'calibri,18'
gnuplot> set ylabel 'Range' font 'calibri,18'
gnuplot> plot 'plot_data_1.txt' with points
gnuplot> quit
plot_1_titled_gifterm.gif

Controlling How Axes Look

Another key to making great-looking plots is to adjust the window to zoom in on the area of interest. You may also want to control how the axes are printed (for instance, do you want the plot area enclosed in a box with axes on either side, or just an x-axis on the bottom and y-axis on the left?). You can also control where (or even if) the major and minor tic marks are placed, and how frequently they appear.

Setting Axis Ranges

To set the range for the X-axis, use the keyword xrange. For example

set xrange [<min>:<max>]

To set the range for the Y-axis, use the keyword yrange in exactly the same way (and the same for zrange if you're doing a surface plot).

The defaults for data files are generally pretty decent, since it simply zooms in around the maxima and minima of the various data sets, but for functions it is generally pretty horrendous (as well it should be — how are the gnuplot programmers to know what part of the curve you think is interesting?).

Setting Tic Levels

To set the tics on the various axes, use the set xtics command (or ytics or ztics depending on what axis you wish to control). The full command is:

set xtics [mirror | nomirror] [in | out] [autofreq | <incr> | <start>,<incr> | <start>,<incr>,<end>] [norotate | rotate]

The meaning of each is as follows:

  • mirror | nomirror : mirror (default) means draw tics on the opposite side of the plot as well. nomirror means only draw tics on the side by the labels.
  • in | out : Either the tics are drawn into the plot (away from the edge of the image) or out of the plot (toward the edge of the image)
  • autofreq | <incr> | <start>,<incr>[,<end>] : The frequency of the tics is chosen either automatically (autofreq, or the start and stop are chosen automatically but the interval is controlled ({<incr>}), or the start and interval between tics are controlled (<start>,<incr>), or the start, stop, and intervals are all controlled (<start>,<stop>,<end>).
  • norotate | rotate : Either rotate (or not, by default) text to align with the direction of the tic marks. For instance, it will rotate the labels on the X-axis by 90o, but keep the labels on the Y-axis horizontal.

For example, take a look at the code below to see how I zoomed in on the region of interest in the data plot and how I modified the look of the X-axis in particular. Notice that the tic marks are going out of the plot area, unlike the Y-axis, and that there are no tic marks on the opposite side, unlike the Y-axis. Also notice how the text is rotated for the tic labels.

gnuplot> set terminal gif font 'calibri,12' size 800,600 enhanced
Terminal type set to 'gif'
Options are 'nocrop enhanced font calibri 12 size 800,600 '
gnuplot> set output 'plot_1_titled_zoomed.gif'
gnuplot> set title 'A Data File Plotted With Points' font 'calibri,25'
gnuplot> set xlabel 'Domain_{independent variable}' font 'calibri,18'
gnuplot> set ylabel 'Range' font 'calibri,18'
gnuplot> set xrange [0.8:1.75]
gnuplot> set xtics nomirror out 1.0,0.125,1.75 rotate
gnuplot> plot 'plot_data_1.txt' with points
gnuplot> quit
plot_1_titled_zoomed.gif

Legends

Another common feature of plots that impacts how it looks is the legend, or the key. In every example above, the key has just been the default key. The default key is the function that was plotted (if f(x) is plotted, then the text is f(x).

To remove the legend completely, use the command

unset key

If you want the legend, you can do a number of things with it. You can reposition it around the plotted area, you can enclose it in a box, or you can give the legend a title.

You can also control the label that each plotted function or data file is given in the key on the plot command. See how the last figure is affected by modifying the key:

gnuplot> set terminal gif font 'calibri,12' size 800,600 enhanced
Terminal type set to 'gif'
Options are 'nocrop enhanced font calibri 12 size 800,600 '
gnuplot> set output 'plot_1_titled_key_gifterm.gif'
gnuplot> set title 'A Data File Plotted With Points' font 'calibri,25'
gnuplot> set xlabel 'Domain_{independent variable}' font 'calibri,18'
gnuplot> set ylabel 'Range^{dependent variable}' font 'calibri,18'
gnuplot> set key left top title 'Plot Legend' box linewidth 2
gnuplot> plot 'plot_data_1.txt' with points title 'Data From File'
gnuplot> quit
plot_1_titled_key_gifterm.gif

The command that controls the key is decomposed as follows:

  • set key : Turns the key on (unset key turns the key off)
  • left : Aligns the key to the left of the plot area (inside by default, the keyword outside will put it outside the plot area)
  • top : Aligns the key to the top. At this point, it will be at the top-left hand corner of the plot area
  • title 'Plot Legend' : Gives the legend a title
  • box : Encloses the legend in a box
  • linewidth 2 : Doubles the default line width of the box

Note that you can prevent gnuplot from printing a particular plotted object (function or data file) by setting the title to an empty string:

plot 'data_file.txt' with lines title ''

Labels

You can also add any number of labels that you want to the graph. Notice the label added by the code below:

gnuplot> set terminal gif font 'calibri,12' size 800,600 enhanced
Terminal type set to 'gif'
Options are 'nocrop enhanced font calibri 12 size 800,600 '
gnuplot> set output 'plot_1_titled_key_labeled_gifterm.gif'
gnuplot> set title 'A Data File Plotted With Points' font 'calibri,25'
gnuplot> set xlabel 'Domain_{independent variable}' font 'calibri,18'
gnuplot> set ylabel 'Range' font 'calibri,18'
gnuplot> set key left top title 'Plot Legend' box linewidth 2
gnuplot> set label 1 "Printed label" font 'calibri,14' at 0.25,-1.5 left textcolor rgbcolor "#0000FF"
gnuplot> plot 'plot_data_1.txt' with points title 'Data From File'
gnuplot> quit
plot_1_titled_key_labeled_gifterm.gif

The command that controls the label is decomposed as follows:

  • set label 1 : Creates a label whose ID is 1, so any reference to label 1 will resolve to this label. It can be any integer
  • "Printed label" : The text of the label
  • font 'calibri,14' : Sets the font and font size of the label
  • at 0.25,-1.5 : Puts the label at these coordinates (not pixels, but the coordinates in the coordinate system of the plot)
  • left : The point described via the at keyword is placed at the left of this text block
  • textcolor rgbcolor "#0000FF" : Sets the color of the label to the hexadecimal value 0000FF (0 Red, 0 Green, 255 Blue). The default color is just black.

Arrows

Sometimes you want to draw attention to something on a graph using an arrow. So you want to combine an arrow with a label to point something out. To print an arrow to the plot, use set arrow. The syntax is as follows:

set arrow from <position> to <position> [nohead | head | backhead | heads] [arrowstyle <style_number>]

To print a line, use nohead. The default, which prints an arrow head at the to position, has the keyword head. To put an arrow head at the from position, use the backhead keyword, and to have a double-headed arrow, use the keyword heads. You can control the arrow style via the arrowstyle <style_number>, much like you can control the line style or point style. Also like the line and point styles, these are terminal-dependent, so play around and see what you like best.

An example using this syntax is shown below, adding onto the previous example. Notice how I use the position of the label and the left keyword to control the relative placement of the arrow and the label very easily. You should use the location keyword for the label that matches the position you want the arrow to take with respect to the label. In the next example, I want the arrow placed on the right side of the label.

gnuplot> set output 'plot_1_titled_key_labeled_arrow.gif'
gnuplot> set title 'A Data File Plotted With Points' font 'calibri,25'
gnuplot> set xlabel 'Domain_{independent variable}' font 'calibri,18'
gnuplot> set ylabel 'Range' font 'calibri,18'
gnuplot> set key left top title 'Plot Legend' box linewidth 2
gnuplot> set label 1 "Turning Point" font 'calibri,14' at 0.5,-1.5 right textcolor rgbcolor "#0000FF"
gnuplot> set arrow 1 from 0.5,-1.5 to 0.85,0.01 linetype -1 linewidth 2
gnuplot> plot 'plot_data_1.txt' with points title 'Data From File'
gnuplot> quit
plot_1_titled_key_labeled_arrow.gif

Print Variables in Legends and Labels

There may come a point where you define a variable that has some value (whether it's given that value during fitting a function to some data or whether you assign it yourself), and you wish to include that variable's value in a legend entry or a label. To do that, you define the string the same way you would in a C program — using sprintf(). Instead of defining a string like:

title 'a = 10'

you can use

title sprintf("a=%d",10)

Look at the example below and the resulting image:

gnuplot> set term gif font 'calibri,12' size 800,600 enhanced
Terminal type set to 'gif'
Options are 'nocrop enhanced font calibri 12 size 800,600 '
gnuplot> set output 'polynomial_plot_with_vars.gif'
gnuplot> f(x) = a*x**2 + b*x + c
gnuplot> set title "Polynomial (ax^2+bx+c)" font 'calibri,25'
gnuplot> set xlabel "X-axis" font 'calibri,18'
gnuplot> set ylabel "Y-axis" font 'calibri,18'
gnuplot> a = 1
gnuplot> b = -1
gnuplot> c = 3
gnuplot> plot f(x) with lines title sprintf("a=%.1f, b=%.1f, c=%.1f",a,b,c)
gnuplot> quit
polynomial_plot_with_vars.gif

More Advanced Plotting

When I first introduced plotting above, I described how to customize your plots a little bit by plotting with points, lines, or both lines and points (these are valid for both functions and data, alike). Now I will get into some more advanced ways of adjusting the appearance of your plots.

Making functions look smoother

The way gnuplot plots functions is to evaluate your function at a number of equal-spaced intervals and connect those points with lines. Thus, in order to get a smooth curve, these points must be significantly closer together than the span in which the function turns around. The default number of points that gnuplot uses is 100. For the functions plotted above, the plots are clearly smooth because the function does not radically change direction within 1/100 of the space of the graph. Let's consider the function sin(4*x), though, and see what happens when we plot that function.

gnuplot> set terminal gif font 'calibri,12' size 800,600 enhanced
Terminal type set to 'gif'
Options are 'nocrop enhanced font calibri 12 size 800,600 '
gnuplot> set output "sin4x_normal_sample.gif"
gnuplot> unset key
gnuplot> plot sin(4*x)
gnuplot> quit
sin4x_normal_sample.gif

Notice how jagged the points of the function are, since there are areas of the curve in which the curvature is very large compared to the spacing between the sampling points. To smooth this function out, we need to take more samples. We can do this via the command

set samples <integer>

where the given <integer> is the number of samples you wish to take. Note that the higher this number is the smoother your plot will be, but the longer the plot will take to render. (This isn't as much a problem for 1-D plots as it is for 2-D surface plots where there are samples in both axes and the number of points scales as the product of the two sampling numbers). See how we modify the above plot by using set samples:

gnuplot> set term gif font 'calibri,12' size 800,600 enhanced
Terminal type set to 'gif'
Options are 'nocrop enhanced font calibri 12 size 800,600 '
gnuplot> set output "sin4x_1000samples.gif"
gnuplot> unset key
gnuplot> set samples 1000
gnuplot> plot sin(4*x)
gnuplot> quit
sin4x_1000samples.gif

Notice how the curve is much smoother and how it actually reaches its correct max and min values (1 and -1, respectively).

Changing How Lines and Points Look

Gnuplot also gives us control over how our lines and points look. We can give our lines and points different colors, different styles, and different sizes or thickness. This applies to both Function plotting and Data File plotting

Changing line and point colors / styles

To change the color or style of the line or point, use the linetype (or lt) keyword followed by an integer. Different terminals typically have different colors and/or styles for different values, so you'll need to experiment a little bit to figure out which integer line type corresponds with which style. In my experience, the type index -1 corresponds to black in colorful terminals.

Changing Line Width and Point Size

Lastly, you can vary how thick the lines appear or how big the points appear by using linewidth <factor> or pointsize <factor>. The factor is a multiplicative scaling factor that determines the size or thickness by multiplying the "default" thickness or size by that factor. Thus, by definition, factors of 1 are default.

An example combining all of these concepts on our data file:

gnuplot> set terminal gif font 'calibri,12' size 800,600 enhanced
Terminal type set to 'gif'
Options are 'nocrop enhanced font calibri 12 size 800,600 '
gnuplot> set output 'plot_1_new_styles.gif'
gnuplot> unset key
gnuplot> plot 'plot_data_1.txt' with linespoints linetype -1 linewidth 3 pointsize 1.5
gnuplot> quit
plot_1_new_styles.gif

Advanced Datafile Plotting

Sometimes a simple plot 'datafile' with lines simply doesn't do what you want it to do. For instance, sometimes you want to adjust the value of the x-axis by a factor to transform "frame number" into "time", or you don't want to use the first two columns of data in the file.

Still other times you may want to adjust a data set according to some function (for instance if you have fit a function and wish to subtract the value of that fitted function to look at residual errors or something). That is what this section addresses.

Also, you may want to add error bars to your data points, or you may want to plot histograms or bars instead of the traditional points and lines.

Plotting data from different columns

To plot data from different columns, you need the using <column1>:<column2> keyword. In cases where more than 2 data columns are necessary, just add :<column_N for the number of columns you need. For instance, to use the 3rd column as the X-coordinate and the 8th column of a text file as the Y-coordinate:

plot 'data_file.txt' using 3:8 with lines

Transforming Plotted Data

To transform a particular column of a data file when plotting, you need to use a variant of the using keyword. For instance, to scale the X-coordinates by a particular scaling factor, use the syntax using ($1*<factor>):2. See the example below:

gnuplot> set term gif font 'calibri,12' size 800,600 enhanced
Terminal type set to 'gif'
Options are 'nocrop enhanced font calibri 12 size 800,600 '
gnuplot> set output 'plot_1_scaled_xaxis.gif'
gnuplot> unset key
gnuplot> plot 'plot_data_1.txt' using ($1*100):2 with points
gnuplot> quit
plot_1_scaled_xaxis.gif

Likewise, you can transform data by a function as well — either a user-defined function or a built-in function like log10(). For example, below I translate the whole plot 2 units up and turn the X-axis into a logarithmic scale.

gnuplot> set term gif font 'calibri,12' size 800,600 enhanced
Terminal type set to 'gif'
Options are 'nocrop enhanced font calibri 12 size 800,600 '
gnuplot> set output 'plot_1_modified_translated_xaxis.gif'
gnuplot> unset key
gnuplot> plot 'plot_data_1.txt' using (log10($1)):($2+2) with points
gnuplot> quit
plot_1_modified_translated_xaxis.gif

Adding Error Bars

gnuplot makes it very easy to add error bars. The values for the error bars must be added as an additional data column in your data file (and can be selected via the use keyword as described above for selecting X- and Y- values). The error bar columns can take a number of formats that will be understood by gnuplot:

  • <delta> : A single column describing how wide the error bars should be with the data point placed in the center. Only X- or Y- error bars can be chosen with this
  • <low> <high> : 2 Data columns describing the low end of the error bar and the high end of the error bar. This is how 2 columns are interpreted when only X- or Y-error bars are asked for.
  • <x-delta> <y-delta> : 2 Data columns describing the width of the X-error bars and the Y-error bars with the data point in the middle. This is how 2 columns are interpreted when both X- and Y- error bars are asked for.
  • <x-low> <x-high> <y-low> <y-high> : 4 Data columns describing both ends of the error bars in both the X- and Y- directions. If 4 columns are specified, both X- and Y-error bars must be turned on.

Note that we don't really need all of the columns that are available if we are able to specify something else for the error bars with the using keyword. The code below will add error bars of full width 0.2 (so 0.1 on either side of the point) in the Y-direction using the same data file we've been using so far:

gnuplot> set terminal gif font 'calibri,12' size 800,600 enhanced
Terminal type set to 'gif'
Options are 'nocrop enhanced font calibri 12 size 800,600 '
gnuplot> set output 'plot_1_with_errorbars.gif'
gnuplot> unset key
gnuplot> plot 'plot_data_1.txt' using 1:2:(0.2) every 10 with yerrorbars, 'plot_data_1.txt' with lines linetype -1 
gnuplot> quit
plot_1_with_errorbars.gif

Because there were so many data points in the file, I used the keyword every 10 to only plot every 10th point. Then I plotted the same data file with lines in the same plot to give the full image.

Also note the 0.2 is in ()s. If a number is not in parentheses following the using keyword, it will be interpreted as a column, so any column manipulation or constant value should appear in parentheses, and columns should be denoted with $#, for whatever column number it is (i.e. $1, $2, etc.).

Two X- and/or Y-axes in One Plot

At times you want to plot two functions on the same plot, but each function has a different range. For instance, suppose you want to plot a bunch of data as well as the autocorrelation function of that data on the same plot. The autocorrelation function is bounded between -1 and 1, whereas your data may be anywhere. Therefore, you will set the left Y-axis to the data and the right Y-axis to the autocorrelation function.

There is a second X- and Y- axis that you can modify (x2 and y2). You can modify them just like any other. (e.g., set y2range [-1:1]). Then you can specify axes [x1y1|x1y2|x2y1|x2y2] on the plot line for any graph to select the two axes you want that function or data to be plotted against.

An example script is shown below with the resulting graph (data is available here):

set term gif font 'calibri,16' size 1024,768 enhanced
set output 'deprot_traj_prot_rlx.gif'

set y2range [-1:1]
set ytics nomirror
set y2tics out -1,0.2,1 nomirror
set title 'Deprot. Traj Relaxation Energy and Autocorrelation' font 'calibri,25'
set ylabel 'Energy (kcal/mol)' font 'calibri,20'
set y2label 'Autocorrelation Value' font 'calibri,20'
set xlabel 'Time or Lag (ps)' font 'calibri,20'

plot 'deprot_traj_prot_rlx_deprot_minus_prot.dat' \
     u ($1*0.02):2 w l lw 2 axes x1y1 title 'Energy Difference', \
     'deprot_traj_prot_rlx_deprot_minus_prot_corr.dat' \
     u ($1*0.02):2 w l lw 2 axes x2y2 title 'Autocorrelation'

The resulting plot is here:
deprot_traj_prot_rlx.gif

Surface Plots (3-D plots)

Here I will discuss how to generate and modify surface plots for both functions of 2 variables and data with 2 variables. I will demonstrate surface plots and their features using functions and introduce plotting 2-D data at the end.

Plotting Surfaces

Surface plots have a different command: splot. However, it is analogous to plot in many ways. While a plotted function should be some function of x, functions for a surface plot should be functions of x and y. For example:

gnuplot> set terminal gif font 'calibri,12' size 800,600 enhanced
Terminal type set to 'gif'
Options are 'nocrop enhanced font calibri 12 size 800,600 '
gnuplot> set output 'splot_function.gif'
gnuplot> unset key
gnuplot> f(x,y)=sin(x)*cos(y)
gnuplot> splot f(x,y)
gnuplot> quit
splot_function.gif

Surfaces are plotted as a series of cross-sections drawn onto a 3-D grid. Each cross-section is plotted like a regular 2-D function. That is, at the given value of x or y, the 3-D function is sampled a given number of times (100 by default — see set samples in the function smoothing above). The frequency with which these cross-sections are sampled is controlled by the isosamples variable.

Making Surfaces Smoother and More Complete

You can see that this surface is not particularly clear, since the sampling of the cross-sections is fairly infrequent. You can increase the number plotted cross-sections by using the set isosamples command, and you can improve the resolution of each cross-section by using the set samples command as we've already demonstrated for 2-D functions. Be careful with this, though. The number of points that need to be calculated (and thus the time it takes to render a surface) grows very quickly as you increase the number of isosamples. See how the above graph is modified when we increase the number of isosamples from its default value of 10 to 100:

gnuplot> set terminal gif font 'calibri,12' size 800,600 enhanced
Terminal type set to 'gif'
Options are 'nocrop enhanced font calibri 12 size 800,600 '
gnuplot> set output 'splot_function_many_isosamples.gif'
gnuplot> unset key
gnuplot> f(x,y)=sin(x)*cos(y)
gnuplot> set isosamples 100
gnuplot> splot f(x,y)
gnuplot> quit
splot_function_many_isosamples.gif

Adjusting the Viewing Angle

Adjusting the viewing angle is controlled by set view. It is used as follows:

set view <rot_x>[,<rot_z>]

It defines a rotation around the X-axis (x_rot) and optionally a rotation around the Z-axis (rot_z). The initial layout (before any rotations are applied, or under set view 0,0, is a right-handed coordinate system with the positive X-axis as the horizontal axis pointing to the right, the positive Y-axis as the vertical axis pointing up, and the positive Z-axis as the axis coming out of the screen directly at you. The default view is equivalent to

set view 60,30

Play around with this to get comfortable with it.

Making a Contour Plot

Many times what you are interested in is a contour plot. To make a contour plot of the function we plotted above, use

set contour [base | surface | both]

The most common option is base, which puts the contours on the X-Y plane. surface puts the contour lines on the surface, and both puts the contour lines on both the surface and the X-Y plane.

And to control the look of the contour lines, we use

set cntrparam

There are 2 different (common) cntrparams that are often modified.

set cntrparam [linear | cubicspline | bspline]

The above controls the interpolation method between points on the same isoline. linear draws straight lines between adjacent points, whereas cubicspline interpolates the values between them using (you guessed it) cubic splines. This results in a much smoother plot. bspline results in an even smoother plot, but actually approximates the values known to be on a given isoline.

If you choose bspline, you can choose the order of the spline used to interpolate via

set cntrparam order <n>

where n is an integer $2 \le n \le 10$

See how we add contour lines to the plot above:

gnuplot> set terminal gif font 'calibri,12' size 800,600 enhanced
Terminal type set to 'gif'
Options are 'nocrop enhanced font calibri 12 size 800,600 '
gnuplot> set output 'splot_function_contour_with_surface.gif'
gnuplot> f(x,y)=sin(x)*cos(y)
gnuplot> set key outside top right
gnuplot> set isosamples 100
gnuplot> set contour base
gnuplot> set cntrparam levels auto 10
gnuplot> splot f(x,y)
gnuplot> quit
splot_function_contour_with_surface.gif

If we just want to see the contour plot, we can remove the surface and adjust the view to look head-on:

gnuplot> set terminal gif font 'calibri,12' size 800,600 enhanced
Terminal type set to 'gif'
Options are 'nocrop enhanced font calibri 12 size 800,600 '
gnuplot> set output 'splot_function_contour_without_surface.gif'
gnuplot> f(x,y)=sin(x)*cos(y)
gnuplot> set key outside top right
gnuplot> set isosamples 100
gnuplot> set contour base
gnuplot> set cntrparam levels auto 10
gnuplot> unset surface
gnuplot> unset ztics
gnuplot> set view 0,0
gnuplot> splot f(x,y)
gnuplot> quit
splot_function_contour_without_surface.gif

Colorful Surfaces

Since version 4.0 (or something around there), gnuplot added the ability to add colored surfaces via set pm3d. The command is formatted as:

set pm3d [at b | at t | at s]

where you can put the colored map superimposed on the surface, as a flat image at the bottom, or as a flat image at the top. In all of these cases, it is probably a good idea to turn the surface off for the same reason as we turned off the surface in the above contour plot example.

An example is shown below:

gnuplot> set terminal gif font 'calibri,12' size 800,600 enhanced
Terminal type set to 'gif'
Options are 'nocrop enhanced font calibri 12 size 800,600 '
gnuplot> set output 'splot_function_pm3d.gif'
gnuplot> f(x,y)=sin(x)*cos(y)
gnuplot> set key outside top right
gnuplot> set isosamples 100
gnuplot> set pm3d at s
gnuplot> unset surface
gnuplot> splot f(x,y)
smooth palette in gif: using 160 of 160 available color positions
gnuplot> quit
splot_function_pm3d.gif

Changing Color Schemes

Gnuplot offers almost infinite flexibility when it comes to setting the color scheme for your plots so that you're not limited to the scheme above. You can choose color schemes in grayscale as well, for plots that will be entering a black-and-white publication or something.

On this page is a reference for different color schemes that some may think are pretty and the RGB formulae used to produce them.

There are many ways of specifying colors (in different color spaces, even). For the purposes of this tutorial/reference, though, we will stick with RGB (Red/Green/Blue) color space, and setting palettes via the rgbformula. This formula is a built-in formula that gnuplot uses to interpolate colors at different values of the color range, and is defined by 3 colors.

The gnuplot help function provides 7 nice-looking RGB formula presets (including the default one). They are, starting with the default:

  • 7,5,15 … traditional pm3d (black-blue-red-yellow)
  • 3,11,6 … green-red-violet
  • 23,28,3 … ocean (green-blue-white); try also all other permutations
  • 21,22,23 … hot (black-red-yellow-white)
  • 30,31,32 … color printable on gray (black-blue-violet-yellow-white)
  • 33,13,10 … rainbow (blue-green-yellow-red)
  • 34,35,36 … AFM hot (black-red-yellow-white)

To change the color scheme, use the following command:

set palette rgbformulae <number>,<number>,<number>

As an example, the script above changes the palette to 33,13,10 for a rainbow image:

gnuplot> set terminal gif font 'calibri,12' size 800,600 enhanced
Terminal type set to 'gif'
Options are 'nocrop enhanced font calibri 12 size 800,600 '
gnuplot> set output 'splot_function_pm3d_rainbow.gif'
gnuplot> f(x,y)=sin(x)*cos(y)
gnuplot> set key outside top right
gnuplot> set isosamples 100
gnuplot> set pm3d at s
gnuplot> set palette rgbformulae 33,13,10
gnuplot> unset surface
gnuplot> splot f(x,y)
smooth palette in gif: using 160 of 160 available color positions
gnuplot> quit
splot_function_pm3d_rainbow.gif

Defining your own color range

Perhaps you want to play around and develop your own color scheme. The easiest way to do this is by defining a color ladder. What I mean by this is you define the colors that your plot has at various values, and gnuplot will interpolate between these for you. For instance let's create a color scheme that moves from royalblue through turqouise through yellow and finally ending on red. (To get a full list of colors that gnuplot has assigned names to, use the command show colornames).

To set this palette with our proposed color scheme for our plot, use the command

set palette defined (0 "royalblue",1 "turquoise",3 "yellow",5 "red")

This is normalized to span 0 to 1, so in this way it is easier to control how quickly each color shift happens in the palette. The effect of using this palette is:

gnuplot> set terminal gif font 'calibri,12' size 800,600 enhanced
Terminal type set to 'gif'
Options are 'nocrop enhanced font calibri 12 size 800,600 '
gnuplot> set output 'splot_function_pm3d_custom_palette.gif'
gnuplot> f(x,y)=sin(x)*cos(y)
gnuplot> set key outside top right
gnuplot> set isosamples 100
gnuplot> set pm3d at s
gnuplot> set palette defined (0 "royalblue",1 "turquoise",3 "yellow",5 "red")
gnuplot> unset surface
gnuplot> splot f(x,y)
smooth palette in gif: using 160 of 160 available color positions
gnuplot> quit
splot_function_pm3d_custom_palette.gif

If you have found a color scheme that you like, you should fit this pre-defined color scheme to gnuplot's rgbformulae. They make this very easy via show palette fit2rgbformulae. Gnuplot will fit our color palette to -10,-13,-26.

gnuplot> set palette defined (0 "royalblue",1 "turquoise",3 "yellow",5 "red")
gnuplot> show palette fit2rgbformulae
        The best match of the current palette corresponds to
            set palette rgbformulae -10,-13,-26

gnuplot>

Let's see how our plot changes when we set the palette via these rgbformulae compared to the last image:

gnuplot> set terminal gif font 'calibri,12' size 800,600 enhanced
Terminal type set to 'gif'
Options are 'nocrop enhanced font calibri 12 size 800,600 '
gnuplot> set output 'splot_function_pm3d_custom_palette_rgbform.gif'
gnuplot> f(x,y)=sin(x)*cos(y)
gnuplot> set key outside top right
gnuplot> set isosamples 100
gnuplot> set pm3d at s
gnuplot> set palette rgbformulae -10,-13,-26
gnuplot> unset surface
gnuplot> splot f(x,y)
smooth palette in gif: using 160 of 160 available color positions
gnuplot> quit
splot_function_pm3d_custom_palette_rgbform.gif

The two images are very similar.

Surface Plots of Data Files

So far we've seen surface plots of functions. There's no additional differences between data files and functions for splot that don't already exist for plot, so I focus here just on the format requirements for surface plot data.

Every line that comes directly after the previous line will be connected to the point before it if plotted with lines. The way data files are typically formatted for surface plotting is to plot isolines in the same way gnuplot plots function surfaces. If you do not have a blank line between different isolines, though, gnuplot will connect them, making your surface look very strange.

In order to get a "good"-looking surface plot, you should make sure that a space (and only a single space!) exists between isolines.

This first file does not have the spaces between isolines. This second file does. See how the two differ:

splot_spaces_comparison.gif

The above image was created with this script.

Notice how the surface plot on the left is nicely gridded (it's a fine grid, so may be difficult to see), but the surface plot on the right is not, and appears to have sharp Vs running up and down the Y-axis. That's because gnuplot was never told (by a blank line) to disconnect points from different isolines.

Fitting Functions to Data

Another very powerful aspect of gnuplot is its ability to fit arbitrary functions to arbitrary data using arbitrary adjustable (fitting) parameters. To fit a function to data, use the fit command as follows:

fit <function> 'datafile' using <x-column>:<y-column> via <variable_1>,<variable_2>,…,<variable_n>

That data file I will be using in this section for examples can be found here, which is a relaxed energy surface of a dihedral scan calculated with a quantum mechanical method.

This data should be periodic, since dihedral angles themselves are periodic, so I will choose a truncated form of a Fourier series expansion to fit this data to. Furthermore, I will only pick even terms, since that is the form of the data. The formula I'm going to use is

(3)
\begin{align} f(x) = a + b \cos(2x) + c \cos(4x) + d \cos(6x) + e \cos(8x) + f \cos(10x) + g \cos(12x) \end{align}

The code below, when run as a script, produces the accompanying image. Notice the elements of this script — it combines most of what we used above to generate this plot. After you run the script, you will see a file called fit.log that has the verbose output of the fitting procedure, including statistics that can help you measure the quality of the fit.

Note that for many kinds of fitting, there is no analytical solution to the best fit, and so an iterative procedure must be used until self-consistency is achieved. In this case, a bad initial choice for some parameters may prevent a good fit from ever being achieved (this is because of the mathematics involved, not because of a shortcoming of gnuplot). To get around this, you'll need to provide a better initial guess (I believe the default is zero, but don't quote me on that). To do that, just assign the variable to a value before you run the "fit" command.

set terminal gif font 'calibri,14' size 800,600 enhanced
set output "quantum_scan_fit.gif"

f(x) = a + b*cos(2*x) + c*cos(4*x) + d*cos(6*x) + e*cos(8*x) + f*cos(10*x) + g*cos(12*x)

set title "Quantum Dihedral Scan" font 'calibri,25'

set xlabel "Dihedral Angle (Radians)" font 'calibri,18'
set ylabel "Potential Energy (kcal/mol)" font 'calibri,18'
set key top left

set samples 1000

fit f(x) 'quantum_profile.txt' using 1:2 via a,b,c,d,e,f,g

plot 'quantum_profile.txt' with points pointsize 2.5 pointtype 3 title '', \
     f(x) with lines linetype -1 linewidth 2 title sprintf("a=%.3f, b=%.3f,\nc=%.3f, d=%.3f,\ne=%.3f, f=%.3f,\ng=%.3f",a,b,c,d,e,f,g)
quantum_scan_fit.gif

Multiplot

The multiplot option allows you to plot multiple graphs in the same canvas. For instance, embedded graphs, a grid of graphs, etc. The way this is done is via

gnuplot> [set up your graph here]
gnuplot> set multiplot [layout rows,cols]
gnuplot> [set up your first graph]
gnuplot> [plot your first graph]
gnuplot> [set up your second graph]
gnuplot> [plot your second graph]
gnuplot> ... etc
gnuplot> unset multiplot # Now you are done
gnuplot> quit

Multiplot: Automatic layout

The layout keyword will set up the graphs in a grid where rows is the number of rows and cols is the number of columns. It will then fill in the graphs from left to right along rows. The code block below plots six different polynomials in different plots in the same image. See how the graphs are filled in according to the 3x2 layout.

gnuplot> set terminal gif size 1200,600 enhanced
Terminal type set to 'gif'
Options are 'nocrop enhanced font arial 12 size 1200,600 '
gnuplot> set output 'multiplot_functions.gif'
gnuplot> unset key
gnuplot> set multiplot layout 2,3
multiplot> set title "x^2"
multiplot> plot x**2
multiplot> set title "x^3-x"
multiplot> plot x**3-x
multiplot> set title "sin(x)"
multiplot> plot sin(x)
multiplot> set title "x**4-x**2+1"
multiplot> set yrange [0:10]
multiplot> set xrange [-5:5]
multiplot> plot x**4-x**2+1
multiplot> set title "x^5"
multiplot> set yrange restore
multiplot> set xrange restore
multiplot> plot x**5
multiplot> set title "x"
multiplot> plot x
multiplot> unset multiplot
gnuplot> quit
multiplot_functions.gif

Multiplot: Creating your own layout

Sometimes you don't want to snap a separate plot to a grid. For instance, suppose you want 3 graphs, the first graph occupies the top half of the image, the second occupies the bottom left quarter, and the third occupies the bottom right quarter. Also, you may want a graph embedded in another graph. These require specific control of your layout, and requires you to specify the location and size of each of your graphs.

To set the location of your first plot, use set origin like so:

set origin <x_location>,<y_location>

Here, <x_location> is a number between 0 and 1 that specifies the where along the horizontal axis the origin of your plot will be (this is the edge of your margins, not the edge of your actual plot). For instance, to have your plot start at the left edge of the screen, use as your <x_location>. To have it start in the middle of the screen, use 0.5 as your <x_location>.

To control how large that particular plot is, use set size like so:

set size <x_size>,<y_size>

Again, <x_size> and <y_size> are numbers between 0 and 1 that determine what fraction of the screen it will take up.

So, to create the layout we described above (with 3 plots), you would use the following template:

gnuplot> set multiplot
multiplot> set origin 0,0.5
multiplot> set size 1,0.5
multiplot> <set up and plot first plot to take up top half of the screen>
multiplot> set origin 0,0
multiplot> set size 0.5,0.5
multiplot> <set up and plot second plot to take up bottom left quarter of the screen>
multiplot> set origin 0.5,0
multiplot> set size 0.5,0.5
multiplot> <set up and plot third plot to take up bottom right quarter of the screen>
multiplot> unset multiplot # now you're done
gnuplot> quit

An example, with the result, is shown below:

gnuplot> set term gif         
Terminal type set to 'gif'
Options are 'nocrop font arial 12 size 640,480 '
gnuplot> set output 'custom_multiplot.gif'
gnuplot> set multiplot
multiplot> set origin 0,0.5
multiplot> set size 1,0.5
multiplot> plot sin(x)
multiplot> set origin 0,0
multiplot> set size 0.5,0.5
multiplot> plot x**3
multiplot> set origin 0.5,0
multiplot> set size 0.5,0.5
multiplot> set xrange [-5:5]
multiplot> set yrange [0:10]
multiplot> plot x**4-x**2+1
multiplot> unset multiplot
gnuplot> quit
custom_multiplot.gif

Margins

If you want to get rid of the spaces in between adjacent plots, you'll need to set margins between your multiplots. You can do this via the following variables:

set tmargin <number>  # Sets the margins on the tops of the plots
set bmargin <number> # Sets the margins on the bottoms of the plots
set lmargin <number> # Sets the margins on the left of the plots
set rmargin <number> # Sets the margins on the right side of the plots

After you do these, don't forget to properly remove any tics from axes you don't want labeled (e.g. any plots on "top" that you just want to correspond to the tics on the plots below) as well as axis labels. Play around and see what you get.

Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License