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.
Table of Contents
|
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:
- 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
- It has an expansive built-in help function to help you every step of the way
- It can print to an almost limitless number of file formats (terminals), so the terminal you want is almost certainly available
- It is incredibly flexible, giving you control over almost every aspect of your graph
- 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)
- The learning curve isn't nearly as steep as you'd think with it being a command-line-only interface
- It's widely used, so there are many, many tutorials and references around for gnuplot (including this one).
- 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)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)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:
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>
with just lines connecting the points
gnuplot> plot 'plot_data_1.txt' with lines
gnuplot>
or with points and lines connecting the points
gnuplot> plot 'plot_data_1.txt' with linespoints
gnuplot>
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
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
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
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
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
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
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
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
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
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
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
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
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
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:
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
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
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
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
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
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
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
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
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:
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)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)
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: 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
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.