Gnuplot

From Torben's Wiki
Jump to: navigation, search

Contents

Basics

Simple Plot

data = 'data.dat'
plot data
#or 
plot sin(x)

Plot multiple lines

plot\
 "1.dat" title "Eins"\
,"2.dat" title "Zwei"\
,"3.dat" title "Drei"\

png output

set terminal png giant size 1024,768
set output "plot.png"
plot sin(x)
unset output

Multiplot / 2 stacked plots

set multiplot layout 2,1 columnsfirst
plot sin(x)
plot cos(x)
unset multiplot

Plot different columns of same file using 2 y-axes

data = 'data.dat'
plot\
 data using 1:3 title "Drei" axes x1y2 \
,data using 1:2 title "Zwei"

Common Mistakes / Errors

Integer division:
use 10.0 / 3 instead of 10/3

Plot Region of Function

plot \
  (x<=0.0)||(x>=0.5)?1/0:sin(x) \
, (x<=0.5)||(x>=1.0)?1/0:cos(x)

Layout

Terminals

set terminal postscript enhanced eps color solid # solid!!!
set terminal png enhanced giant size 1024,768

For PostScript and MP you should

set border back

as otherwise the frame is drawn twice (can be found using inkscape)

My Favorite: Terminal MP (Metapost) (needs Latex and UbuntuPackage texlive-metapost)

#term = "png"
term = "mp"
if (term eq "png" ) set terminal png enhanced giant size 1024,768
if (term eq "mp"  ) set terminal mp color solid latex psnfss prologues 2 magnification 1.00
outfile="plot123"
set output outfile . "." . term
 plot sin(x)
unset output

if (term eq "mp"  ) \
 system ("mpost -tex=latex '".outfile.".mp'") 
 ; system ("mv " . outfile . ".0 " . outfile .".mps") \
 ; system ("convert -density 300 ".outfile.".mps ".outfile.".png") \
 ; system ("rm -f ".outfile.".mpx")
 ; system ("rm -f ".outfile.".log")
 ; system ("rm -f ".outfile.".mp")

General

set title "Plot Title"
# set default plot style
set style function points
# define linestyles
set style line 1 lt 1 lw 2
# Legend position
set key top right # or set key off
# advanced:
set key bottom left box width -3 reverse Left samplen 2 #invert title "Sinus"
# default:
set key on right top vertical Right noreverse noinvert samplen 4 spacing 1.25 title "" nobox

Axes

set xlabel "Time (s)"
set ylabel "Current (A)"
set grid xtics ytics

# set tics
set xtics mirror
set ytics mirror 
# add some tics
set xtics add (0.003, 0.03, 0.3) 
set xtics add ("Pi" 3.14159)

# Disable autorange of axes
set xrange [1:*]
set yrange [2.8E-08:3.0E-08]
set logscale y
# set format of number to 1e-03 etc
set format y "%1.e"
# 10^x
set format y "10^{%L}"
# "%" sign:
set format y "%g%%"
# % sign in Terminal MP (Latex)
set format y "%g".'\%%'
# NullAchsen einfügen
set zeroaxis
# or
set xzeroaxis ls -1 lw 2

Linked axes

Linked tics on top axes e.g. bottom=nanometer/top=eV [1]

set x2label "Temp (C)"
set x2tics (\
   "25" 1000/(c0C+25) \
,  "50" 1000/(c0C+50) \
,  "75" 1000/(c0C+75) \
,  "100" 1000/(c0C+100) \
,  "125" 1000/(c0C+125) \
)

Important: you have to set plot range for x and x2!!!

plot [xmin:xmax] [*:*] [xmin:xmax]

Links: [2]

Add Text to Plot

set label "text" at 3.3e-3,90e-3
plot ...

set label 1 sprintf("Ea = %3.5g",-b*ckb/ce) at 3.3e-3,90e-3
plot ...
unset label 1
# position can be given via differnet systems: first (=x axes), second (=x2 axes), graph (=pos in graph area 0.0..1.0) , screen, character
# see help set coordinates
set label "text" at graph 0.25, graph 0.75

Colors

set color of axes label or tics to that of line XYZ

set ylabel "Label" textcolor lt 1
set ytics textcolor lt 1

Draw Line/Arrow

set arrow nohead from 0,0 rto 10,1
set arrow from fitLow, graph 0 to fitLow, graph 1 nohead lc -1 lw 2
plot ...
unset arrow

Note: set arrow must be placed before the plot command

Draw circle, rectangle, ellipse, or polygon

set object 1 circle at xwert , ywert behind

Fonts

in Linux run

export GDFONTPATH=/usr/share/fonts/truetype/msttcorefonts

than you can use all the fonts in that dir. For example

set terminal png giant font "Arial,24"
Latex Fonts

From [3], needs Linux package "cm-super")

set term postscript fontfile '/usr/share/texmf/fonts/type1/public/cm-super/sfrm1000.pfb' "SFRM1000"

or after copying the file

set term postscript fontfile '/MessSoftware/sfrm1000.pfb' "SFRM1000"
Greek Symbols in Latex

To get a greek letter, you have to use the postscript terminal, with the option enhanced. Then, to add the alpha greek letter, you have to type {/Symbol a}. Analogously for other letters, changing the "a" by other, like "D" for Delta and so on... [4]

Modify Default Line Types/Styles

set style line  1 lw 2
set style line  2 lw 2
set style line  3 lw 2
set style line  4 lw 2
set style line  5 lw 2
set style line  6 lw 2
set style line  7 lw 2
set style line  8 lw 2
set style line  9 lw 2
set style line 10 lw 2
set style increment user # important!!! switch between linetypes (default) and userdefined linestyles

Fitting

b=5
f(x) = x**b
fit f(x) "data.dat" using 1:2 via b
plot "data.dat" title "data" notitle, f(x) title "fit"
# to weight the data (here by y^(-2)) use sth like the following:
# fit f(x) "data.dat" using 1:2:(1./$2**2) via b
f05(x)=a05*exp(b05*x)+0
fit [0.003:0.006] f05(x) "V6_05.dat" using (1./(($3/2+$4/2)+273.15)):($2*5380716) via a05,b05
a=1; b=1
f(x)=a*exp(b*x)
fitLow =0.0030
fitHigh=0.0055
fit [fitLow:fitHigh] f(x) "data.dat" via a,b
print a,b
set output "png/fit.png"
plot \
  "data.dat" title  "5V" with points pointsize 0.2\
, (x<=fitLow)||(x>=fitHigh)?1/0:f(x) notitle with lines \
unset output

Interpolate

smooth csplines

Advanced Fitting

FIT_LIMIT = 1e-8 # or even smaller

restricting fit parameters

f(x) = a   *exp(-(x-b   )*(x-b   )/c   /c   ) 
g(x) = A(a)*exp(-(x-B(b))*(x-B(b))/C(c)/C(c))

# trick: use atan as restriction function
A(x) = (2.0-1.1)/pi*(atan(x)+pi/2)+1.1 # Restrict a to the range of [1.1:2.0]
B(x) = (0.9-0.1)/pi*(atan(x)+pi/2)+0.1 # Restrict b to the range of [0.1:0.9]
C(x) = (1.5-0.5)/pi*(atan(x)+pi/2)+0.5 # Restrict c to the range of [0.5:1.5]

a =0.0 ; b =0.5 ; c =0.9 ; 
fit f(x) 'data.dat' via a, b, c
aa=1.5 ; bb=0.5 ; cc=0.9 ;
fit g(x) 'data.dat' via aa, bb, cc
plot "data.dat" , f(x) , g(x)

print A(aa), B(bb), C(cc) # do NOT use aa, bb, cc as they are not what you want!!!

Misc

Errorbars

plot data u ($1):($5):(0.1*$1):(0.1*$5) w xyerrorbars ps 0
plot data u ($1):($5):(0.1*$1) w xerrorbars
plot data u ($1):($5):(0.1*$5) w yerrorbars

Dashed lines

In terminal mp (which I prefere) use terminal option dashed and redefine the linestyles using lt 1 (solid) as template

set style line 1 lt 1 linecolor rgb "red"
set style line 2 lt 1 linecolor rgb "blue"
set style line 3 lt 1 linecolor rgb "magenta"

Furthermore define how your dashed (e.g. lt 6 as template) line shall look like and define e.g. ls 30 to it

set style line 30 lt 6 lw 1 linecolor rgb "dark-green"

Now you can plot data and line by

plot data u 1:5 ls 2
set arrow from 0.55, graph 0 to 0.55, graph 1 nohead ls 30 back

number or Points to plot for analytic function

set samples 200 # default = 100

pause

you can use

pause mouse

to let gnuplot stop continuing until you click the mouse

Find min / max value

using Perl

max=`! perl -e '$max=-1e38; while (<>) {@t=split;  $max=$t[1] if $t[1]>$max}; print $max' < 22.5.dat`
min=`! perl -e '$min=+1e38; while (<>) {@t=split;  $min=$t[1] if $t[1]<$min}; print $min' < 22.5.dat`
print min,max

Version 2

s = '$col=2; $f='."'".data."'".'; use warnings; \
  open (FH, $f); @a = grep {not m/^#/ and not m/^\s*$/ } <FH>; close FH; \
  @t=split /\t/ , shift @a ; $x=$t[$col-1];  print $x '
first=system("perl -e \"".s."\"")
print first

s = '$col=2; $f='."'".data."'".'; use warnings; \
  open (FH, $f); @a = grep {not m/^#/ and not m/^\s*$/ } <FH>; close FH; \
  @t=split /\t/ , pop @a ; $x=$t[$col-1];  print $x '
last=system("perl -e \"".s."\"")
print last

s = '$col=2; $f='."'".data."'".'; use warnings; $x=1e38;\
  open (FH, $f); @a = grep {not m/^#/ and not m/^\s*$/ } <FH>; close FH; \
  while ($l=shift @a) { @t=split /\t/,$l ; next if $#t<$col-1 ; $x=$t[$col-1] if $t[$col-1]<$x;} ;  print $x '
min=system("perl -e \"".s."\"")
print min

s = '$col=2; $f='."'".data."'".'; use warnings; $x=-1e38;\
  open (FH, $f); @a = grep {not m/^#/ and not m/^\s*$/ } <FH>; close FH; \
  while ($l=shift @a) { @t=split /\t/,$l ; next if $#t<$col-1 ; $x=$t[$col-1] if $t[$col-1]>$x;} ;  print $x '
max=system("perl -e \"".s."\"")
print max

Version 2a - Linux

s = '$col=5; $f="'.data.'"; use warnings; $x=1e38;\
  open (FH, $f); @a = grep {not m/^#/ and not m/^\s*$/ } <FH>; close FH; \
  while ($l=shift @a) { @t=split /\t/,$l ; next if $#t<$col-1 ; $x=$t[$col-1] if $t[$col-1]<$x;} ;  print $x '
min=system("perl -e \"".s."\"")
print min

Version 3 (when using Perl to gen Gnuplot script)

my $colX=3; my $colY=2; 
open (FH, $f);
my @a = grep {not m/^#/ and not m/^\s*$/} <FH>;
close FH;
my @b=split /\t/ , pop @a ; 
my $lastX=$b[$colX-1];
my $lastY=$b[$colY-1];

$cont .= "set object 1 circle at $lastX , ($lastY*1E9) behind\n";

Variables

a=123
print "Variable a=",a
undef a

Export (fit-)Variables

a=12
system(sprintf("echo A=%d >testausgabe.txt",a))

Schnippsel

c0C = 273.15
ckb = 1.38e-23
ce  = 1.602e-19
ckbeV = ckb/ce
set x2tics (\
   "25" (c0C+25) \
,  "50" (c0C+50) \
,  "75" (c0C+75) \
,  "100" (c0C+100) \
,  "125" (c0C+125) \
)

WARNING: you have to set x2 AND x ranges to the same! (so no autorange :-()

Multiplot advanced

Plots 3 graphs using same x-axis
Problem: commands size and origin include margins, so complicated to paint 3 graphs of same size of plot area

# set axis position to fixed position
set lmargin 8
set rmargin 10
set size 1.0,1.0

set grid xtics x2tics ytics y2tics -1
set key center top box

xmin = 1E-3
xmax = 1
set samples 1000

set logscale x
set logscale x2
set xrange  [xmin:xmax]
set x2range [xmin:xmax]

set xlabel "Doping (MR)"

set multiplot

# plot 1(bottom)
set size 1.0 , 1.0/3
set origin 0.0,0.0
set bmargin 4 ; set tmargin 0 ; set xlabel "Doping (MR)"
set xtics mirror (1E-3, 1E-2, 1E-1, 1)
set ylabel "Cond." ; set ytics  0.5 mirror
unset y2tics ; unset y2label
plot sin(x)

# plot 2(middle)
set size 1.0 , 1.0/3
set origin 0.0 , 1.0/3
set bmargin 0 ; set tmargin 0;  unset xlabel
set xtics mirror ("" 1E-3, "" 1E-2, "" 1E-1, "" 1)
unset ytics ; unset ylabel
set y2label "Seebeck" ; set y2tics 0.5
plot cos(x) with lines lc 2

# plot 2(top)
set size 1.0 , 1.0/3
set origin 0.0 , 1.0/3*2
set bmargin 0 ; set tmargin 2
unset xtics; set x2tics mirror (1E-3, 1E-2, 1E-1, 1)
set ylabel "Eact" ; set ytics  0.2
unset y2tics ; unset y2label
plot sin(x)*cos(x) with lines lc 3

unset multiplot


My Plot Template

allowing to choose between Terminal PNG or MetaPost

Main file plot.gp

#!/usr/bin/gnuplot
load "/MessSoftware/A_gnuplot-header.gp"

term = "png"
term = "mp"

plotfolder = "png_XYZ"
 
data1 = "data/Eins.dat"
data2 = "data/Zwei.dat"

set style data linespoints
set style increment user
set style line  1 linetype 1 lw 2 ps 2
set style line  2 linetype 2 lw 2 ps 2

if (term eq "mp"  ) set terminal mp color solid latex psnfss prologues 2
if (term eq "png" ) set terminal png enhanced giant size 1024,768

data = data1
load "plot_c_vs_d1.gp" # in here is the plot function

data = data2
load "plot_c_vs_d1.gp" # again...

if (term eq "mp"  ) s = "perl convert.pl " . plotfolder ; system (s)


plot file plot1.gp, executed for each data set

f(x) = m*x+b
fit f(x) data using (log($1)):(log($2)) via m,b
fe(x) = x**m * exp(b)
set label 1 sprintf("m=%.2f",m) at graph 0.05, graph 0.75
set output plotfolder . "/" . "." . term
plot \
  data u ($1):($2) notitle \
, fe(x) title "fit" w lines lw 1
unset output ; unset label 1


perl script convert.pl for converting .mp to png and .mps

#!/usr/bin/perl -w
use warnings;use strict;

my $del_mps = 1;
my $dpi = 222.841; # -> 28cm in ooimpress 

my $plotdir = "png";
$plotdir = shift if @ARGV;
chdir $plotdir or die $!;

my @a = <*.mp>;
foreach my $f (@a) {
  print "-->$f\n";
  $_ = $f;
  $f =~ s/ /_/g;
  `mv "$_" "$f"` unless ($_ eq $f);
  my $fname = $f;  
  $fname =~ s/\.[^\.]*?$//; # remove ext
  print system("mpost -tex=latex '$fname.mp'");
  print "\n";
  my @b = grep {m/\.[\d]+$/}  grep {-f $_} <$fname.*>;
  $f = $b[0];
  print `mv "$f" "$fname.mps"`;
  print `convert -density $dpi "$fname.mps" "$fname.png"`;
  print `rm "$fname.mps"` if $del_mps;
  unlink ( split " ", "$fname.eps $fname.mp $fname.mpx $fname.log");
  print "\n";
}

$_ = "mpxerr.tex"; unlink $_ if -f $_;
Personal tools