Gnuplot is a free and open-source commandline driven plotting utility. You can plot high-quality graphs using raw data files or Excel-like program outputs.
Before starting this tutorial, make Lecture10
folder, go to that folder and download the data from here. Right click and click save as. Name it as population.txt
in ~/Lecture10
.
Type gnuplot
on a terminal window to start Gnuplot.
The first file we plot is population.txt
. Run the following command after running Gnuplot on your terminal.
gnuplot> plot 'population.txt'
Here, Gnuplot reads population.txt
which contains a five-column list. The first column, as default in Gnuplot, is read as the x-axis values of our plot while the second column is y-axis.
We will change the columns later, but you can specify them by us 1:2
.
gnuplot> plot 'population.txt' using 1:2
We can change the legend which seems 'population.txt' us 1:2
on the right-top corner of our graph currently.
To do this we should use title
option in Gnuplot as follows:
gnuplot> plot 'population.txt' using 1:2 title 'Turkiye'
All the options in Gnuplot have their short names to save from the typing time. We can get the same result when we run,
gnuplot> p 'population.txt' us 1:2 t 'Turkiye'
This +
sign can be changed with another sign. To check the available signs in Gnuplot we run
gnuplot> test
To change the point type, we can use linetype
or lt
and the number we choose.
gnuplot> p 'population.txt' us 1:2 t 'Turkiye' lt 7
Prints the output below.
The color can be set to black by lc -1
.
gnuplot> p 'population.txt' us 1:2 t 'Turkiye' lt 7 lc -1
Sometimes we may need to use different colors than the default ones.
Then we can use RGB codes as lc rgb '#FF9876'
for example.
gnuplot> p 'population.txt' us 1:2 t 'Turkiye' lt 7 lc rgb '#FF9876'
Please see this for more color codes.
Some color names can also be used in a similar format. Use lc rgb 'navy blue'
for instance.
We can use lines using with lines
or w l
option.
gnuplot> p 'population.txt' us 1:2 t 'Turkiye' lt 7 lc rgb 'navy blue' w l
Or lines and points together using with linespoints
or w lp
option.
gnuplot> p 'population.txt' us 1:2 t 'Turkiye' lt 7 lc rgb 'navy blue' w lp
Line width is changed by linewidth
or lw
option. But it should be set before w lp
.
gnuplot> p 'population.txt' us 1:2 t 'Turkiye' lt 7 lc rgb 'navy blue' lw 3 w lp
We can change the limits of the axes using
gnuplot> set xrange [1962:2022]
and
gnuplot> set yrange [20000000:90000000]
Then, you can just run replot
to update the graph.
gnuplot> replot
When we set the first year to 1962, the x tics seem weird. We can manually set them as follows:
gnuplot> set xtics (1962,1982,2002,2022)
We can use autofreq 1962,10
to set it starting from 1962 and increasing 10 by 10.
gnuplot> set xtics autofreq 1962,10
Or we can also limit earlier, such as:
gnuplot> set xtics autoreq 1962,10,1992
Similarly, we can use set xlabel 'Year'
and set ylabel
Population` for labels.
The y-axis values of our graph are not easy to read for everyone.
We can divide it to a million by using 1:($2 / 1000000)
and express it on the label of y-axis as follows:
gnuplot> p 'population.txt' us 1:($2/1000000) t 'Turkiye' lt 7 lc rgb 'navy blue' lw 3 w lp
gnuplot> set ylabel 'Population in millions'
gnuplot> set yrange [20:90]
Change the border thickness using,
gnuplot> set border lw 1.5
We can put grids on the graph with the command below.
gnuplot> set grid
If you want to set the grids between the tics, you can use the commands below.
gnuplot> set grid xtics mxtics
gnuplot> set mxtics 5
gnuplot> set grid ytics mytics
gnuplot> set mytics 2
You can also change the grid type from dotted lines to other types.
gnuplot> set grid lt -1, lt 0
Or you can improve it by
set grid lw 1 lt -1 lc rgb 'gray', lw 1 lt 0 lc rgb 'gray'
Until this point, we worked on Gnuplot using commandline. But all the setting will disappear when we press ctrl+d
and exit.
So as to use the same settings on different plots, we can write Gnuplot scripts and use them as template for future works.
Press ctrl+d
and open a file by vi template.gp
.
Write the code below.
#/usr/bin/gnuplot
set xrange [1962:2022]
set yrange [20:90]
set xlabel 'Year'
set ylabel 'Population in millions'
set xtics autofreq 1962,10
set grid xtics lt -1 lw 0.2 lc rgb 'gray'
set grid xtics mxtics
set grid ytics mytics
set mytics 2
set mxtics 5
set grid lw 1 lt -1 lc rgb 'gray', lw 1 lt 0 lc rgb 'gray'
set border lw 1.5
plot 'population.txt' using 1:($2/1000000) t 'Turkiye' lt 7 lc rgb 'navy blue' lw 3 w lp
We can execute this script by,
gnuplot template.gp -p
To save the graph to a file, we first need to define a terminal, and we need to set output. Add the two lines below on the top of your script.
set terminal pdfcairo font 'Times,14' size 4.5in,3.0in
set output 'population.pdf'
Then, run your script. You should have a PDF document on the same directory at the end. You can open it by evince population.pdf
.
The default terminal in Gnuplot is qt
or wxt
depending on the version.
When we change the terminal the point sizes and some of other options we set on qt
change.
To fix it, we can change the point size by adding ps 0.3
option in the line below.
plot 'population.txt' using 1:($2/1000000) t 'Turkiye' ps 0.3 lt 7 lc rgb 'navy blue' lw 3 w lp
And we can change the grid type by changing the line below.
set grid lw 1 lt -1 lc rgb 'dark-gray', lw 0.05 lt -1 lc rgb 'light-gray'
We can add multiple lines into the graph. To do that we can change the line as follows.
plot 'population.txt' using 1:($2/1000000) t 'Turkiye' ps 0.3 lt 7 lc rgb 'navy blue' lw 3 w lp ,\
'population.txt' using 1:($3/1000000) t 'Germany' ps 0.3 lt 4 lc rgb 'red' lw 3 w lp ,\
'population.txt' using 1:($4/1000000) t 'UK' ps 0.3 lt 8 lc rgb 'green' lw 3 w lp
The legend position can be changed by set key right bottom
for example. But I prefer locating the legend outside of the graph. Use following to do it.
set key reverse below Left spacing 2
We can plot the different lines using multiplot method.
#/usr/bin/gnuplot
#set terminal pdfcairo font 'Times,14' size 4.5in,3.0in
set terminal pdfcairo font 'Times,14' size 4.5in,9.0in
set output 'population.pdf'
set xrange [1962:2022]
set yrange [20:90]
set xlabel 'Year'
set ylabel 'Population in millions'
set xtics autofreq 1962,10
set grid xtics lt -1 lw 0.2 lc rgb 'gray'
set grid xtics mxtics
set grid ytics mytics
set mytics 2
set mxtics 5
set grid lw 1 lt -1 lc rgb 'dark-gray', lw 0.05 lt -1 lc rgb 'light-gray'
set border lw 1.5
#set key reverse below Left spacing 2
set key bottom right
set multiplot layout 3,1
unset xlabel
plot 'population.txt' using 1:($2/1000000) t 'Turkiye' ps 0.3 lt 7 lc rgb 'navy blue' lw 3 w lp
unset xlabel
p 'population.txt' using 1:($3/1000000) t 'Germany' ps 0.3 lt 4 lc rgb 'red' lw 3 w lp
set xlabel 'Year'
p 'population.txt' using 1:($4/1000000) t 'UK' ps 0.3 lt 8 lc rgb 'green' lw 3 w lp
unset multiplot
Then the output will be as follows:
We can animate the graphs using Gnuplot. To do it we need to change the terminal and use a for loop as shown below.
#/usr/bin/gnuplot
set terminal gif animate delay 1 font 'Times,14'
set output 'population.gif'
set xrange [1962:2022]
set yrange [20:90]
set xlabel 'Year'
set ylabel 'Population in millions'
set xtics autofreq 1962,10
set grid xtics lt -1 lw 0.2 lc rgb 'gray'
set grid xtics mxtics
set grid ytics mytics
set mytics 2
set mxtics 5
set grid lw 1 lt -1 lc rgb 'dark-gray', lw 0.05 lt -1 lc rgb 'light-gray'
set border lw 1.5
set key reverse below Left spacing 2
do for [i=1:62]{
plot 'population.txt' using 1:($2/1000000) every ::1::i t 'Turkiye' ps 0.3 lt 7 lc rgb 'navy blue' lw 3 w lp ,\
'population.txt' using 1:($3/1000000) every ::1::i t 'Germany' ps 0.3 lt 4 lc rgb 'red' lw 3 w lp ,\
'population.txt' using 1:($4/1000000) every ::1::i t 'UK' ps 0.3 lt 8 lc rgb 'green' lw 3 w lp
}
Then the output can be watched by google-chrome population.gif
as follows.
This animation can be done converting the line graph to bar graph as follows:
#/usr/bin/gnuplot
set terminal gif animate delay 1 font 'Times,14'
set output 'population.gif'
set xrange [1962:2022]
set yrange [20:90]
set xlabel 'Year'
set ylabel 'Population in millions'
set xtics autofreq 1962,10
set grid xtics lt -1 lw 0.2 lc rgb 'gray'
set grid xtics mxtics
set grid ytics mytics
set mytics 2
set mxtics 5
set grid lw 1 lt -1 lc rgb 'dark-gray', lw 0.05 lt -1 lc rgb 'light-gray'
set border lw 1.5
set key reverse below Left spacing 2
set boxwidth 10
set style fill solid
unset xtics
unset xlabel
do for [i=1:62]{
x=i+1961
set title 'Year: '.x
plot 'population.txt' using (1980):($2/1000000) every ::i::i t 'Turkiye' ps 0.3 lt 7 lc rgb 'navy blue' lw 3 w boxes ,\
'population.txt' using (1992):($3/1000000) every ::i::i t 'Germany' ps 0.3 lt 4 lc rgb 'red' lw 3 w boxes ,\
'population.txt' using (2004):($4/1000000) every ::i::i t 'UK' ps 0.3 lt 8 lc rgb 'green' lw 3 w boxes
}
#/usr/bin/gnuplot
set terminal pdf font 'Times,14' size 4.5in,3in
set output 'population.pdf'
set xyplane 0
set yrange [1962:2022]
set zrange [20:90]
set xrange [1:3]
set ytics autofreq 1962,10
set grid ytics lt -1 lw 0.2 lc rgb 'gray'
set grid xtics lt -1 lw 0.2 lc rgb 'gray'
set grid ztics lt -1 lw 0.2 lc rgb 'gray'
set border lw 1.5
set xtics ("Turkiye" 1, "Germany" 2, "UK" 3) offset 0,-1
unset key
splot 'population.txt' using (1):1:($2/1000000) t 'Turkiye' ps 0.3 lt 7 lc rgb 'navy blue' lw 3 w boxes ,\
'population.txt' using (2):1:($3/1000000) t 'Germany' ps 0.3 lt 4 lc rgb 'red' lw 3 w boxes ,\
'population.txt' using (3):1:($4/1000000) t 'UK' ps 0.3 lt 8 lc rgb 'green' lw 3 w boxes