现在在网上可以找的科学作图软件有不少,其中不乏优秀者,Win平台上有大名鼎鼎的Origin、Tecplot、SigmaPlot等,类UNIX上有LabPlot、gnuplot等。其他的常见的计算软件如Matlab、Mathematica、Maple、Scilab、IDL、Maxima等也都对科学作图有很好的支持,甚至于只要稍加努力使用MS的Excel也可以做出不错的图来。但是笔者最喜爱的工具还是gnuplot。gnuplot是典型的UNIX哲学的产物,小巧,灵活,擅长于与其他工具协同工作。本人使用gnuplot已经有1年有余,积累了些经验,下面的内容主要是我1年多来使用gnuplot所做笔记的一个总结,当然,在成稿过程中也将gnuplot的手册又来回翻了几遍。
gnuplot是一个命令行驱动的科学绘图工具,可将数学函数或数值资料以平面图或立体图的形式画在不同种类终端机或绘图输出装置上。它是由ColinKelley和ThomasWilliams于1986年开发的绘图程序发展而来的,可以在多个平台下使用。gnuplot既支持命令行交互模式,也支持脚本。
gnuplot的主要作者包括:ThomasWilliams,ColinKelley,RussellLang,DaveKotz,JohnCampbell,GershonElber,AlexanderWoo和许多其他人。
gnuplot与自由软件基金会和GNU项目没有任何直接的关系,因此将gnuplot称为GNUplot是不对的。gnuplot是完全独立的设计和开发的,命名为gnuplot只是种妥协,当时Thomas希望他们开发的程序叫做"llamaplot"而Colin更喜欢"nplot"这个名字。后来他们都同意命名他们的程序为"newplot",可是很快他们发现有个Pascal语言写的程序叫这个名字,而且这个程序偶尔会被提到。最后Thomas想出了"gnuplot"这个双方都可以接受的名字。
本文中所引用范例皆整理自gnuplotdemo。文中的图例亦引用自子目录demo中的范例。
本文全文都以GNU/Linux下的gnuplot4.0版本为例,如果读者使用的是其他版本的操作系统,个别操作细节请做相应调整。
在命令行模式下输入gnuplot,即可看到如下的信息,其中省略号处省略了部分信息:
GNUPLOTVersion4.0patchlevel0lastmodifiedThuApr1514:44:22CEST2004System:Linux32bit……Terminaltypesetto'x11'gnuplot>
‘gnuplot>’即是gnuplot的命令行提示符,gnuplot的所有命令都在这个提示符下输入。
请看例1:
plotsin(x)
产生图2结果——以曲线绘出三角函数sin(x)。
图1Plottingsin(x)
假设我们只想看到一个正弦曲线周期。我们通过限制图的默认x范围来完成此操作。使用表示法[min:max]来指定范围。要仅指定最小值,使用[min:];要仅指定最大值,使用[:max]。数学上称此为所谓的“闭”区间表示法。
例2从-pi到+pi的sin(x)和cos(x)
setxrange[-pi:pi]replotcos(x)withpointspointtype2
或者:
我们刚才使用了replot命令,它执行先前的plot命令。当您绘制曲线图且需要不断对该图进行修改以添加想要的特征时,此命令会非常有用。另外,replot使您可以添加更多的图。尝试输入replotcos(x)。依照语法,该命令等同于plotsin(x),cos(x)。replot就是获取先前的绘图字符串,添加必要的逗号,然后附加输入给它的其余部分。
例5将数据文件中的数据画出:
plotsin(x),‘1.dat’
其中1.dat为一数据文件,每一行描述一点坐标位置。内容如下,其中#后面的内容为注释:
图2Plottingsin(x),datafile–1.dat
例6命名图和坐标轴:
现在,我们注意到x轴实际没有标记为度数,看起来不是很好。要修改此问题,可以通过调整x轴上的tic标记。
例7改变轴上tic并设置网格:
gnuplot还允许您指定绘图的样式,以便获得进一步的控制。
例8多条曲线
with子句使您可以详细而精确地指定线的样式。在本例中,我们说明两种有用的样式。第一种样式linespoints通常在对数据绘图时非常有用,它在涉及的每个示例或数据点处标记一个点,并使用线性插值法连接连续的点。这里我们另外指定点类型为5,它选择终端允许的第五种点。第二种样式boxes更适合绘制直方图数据。注意我们如何在cos(x)曲线中将with缩写成w。类似地,lt是linetype的缩写,是另一个特定于终端的设置,它选择终端可以绘制的四种线。不必说,您可以使用pt代替冗长的pointtype。如果想在多条线中使用相同的绘图样式(在一个plot命令中或在多个plot命令中),可以使用set命令设置绘图样式:setstylefunctionlinespoints。要更改用于绘制与函数相对的数据集合的样式,使用setstyledatalinespoints。
当绘制两条或多条曲线时,我们需要关键字或图例来对它们进行区分。默认情况下,关键字在右上角;但是如果它妨碍了图,可以将关键字放到其他位置。如果愿意,甚至可以放到图外。
例9定制图的关键字或图例
上面,我们在同一图中绘制了正弦和余弦曲线。gnuplot使您还可以绘制多个图,这样它们可以并排显示在同一输出屏幕或文件中。在某些排版系统中,以一个文件的形式包含两个图形比分别包含两个图形要更容易。
例10Multiplot示例:
例11:
splot[-pi:pi][-pi:pi]sin(x)*cos(y)产生图2结果---以纵横各10条线组成的网格画出sin(x)*cos(y)的图形。
图3Plottingsin(x)*cos(y)
例12画等高线图:
例13画pm3d图
在启动时,您可能注意到终端类型设置为X11。gnuplot采用标准设计,可以在多个终端设备上绘图。这包括直接打印到多种打印机中,包括Epson、HP和Imagen打印机。它甚至可以在伪设备中绘图,如postscript和png。这主要涉及生成输出文件,而不是可查看文件或打印输出。这是将您的图表包含在其他报表中的一种技巧。
例14设置输出和终端类型
setterminalpng#gnuplotrecommendssettingterminalbeforeoutputsetoutput‘output.png’#Theoutputfilenameplotsin(x)现在,文件output.png中有了您刚才绘制的图。
所有终端在能力上都不相同。其中的一些(如LaTeX)可能不支持文本的旋转,所以如果您像我们前面那样设置ylabel,在不同的终端中可能显示不一样。换句话说,您可以在LaTeX的特定终端中使用LaTex命令。例如,setylabel$sin(\\\\theta)$(注意我们使用两个反斜杠产生一个LaTex所需的反斜杠——gnuplot在将双引号中所括的字符串传送到终端驱动程序之前,先对其进行反斜杠处理)。现在,您可以使用\\input{output.tex}将输出文件包含在LaTeX文件中。要在PostScript终端中获得相同的结果,使用相应的PostScript命令:{/Symbolq}。在enhancedPostScript和LaTeX中,您可以使用表示法x^{superscript}和x_{subscript}得到上标文字。还要注意缩写的终端和输出命令:
例15eps驱动程序的能力
settermpostenh#enhancedPostScript,essentiallyPostScriptwithboundingboxessetout'gplt.eps'setxlabel'{/Symbolq_1}setylabel'sin^2({/Symbolq_1})'plotsin(x)**2其他顺便说一下,我们提供的所有例子都可以在交互模式或批处理模式下运行。要以交互模式运行,在提示符中输入每个命令。要以批处理模式运行,将命令输入或添加到文本文件中,然后在gnuplot提示符中使用load'filename'读入文件,或者在shell提示符下将其作为参数提供给gnuplot:$gnuplotfilename。使用第二种方法,gnuplot会在执行输入文件中的所有命令后退出,所以当直接绘图到文件中时,采用批处理模式执行特别有效。如果在屏幕上绘图时使用第二种方法,输出窗口一出现(当gnuplot退出时)就会消失,所以您需要使用显式的“pause-1”命令(请参阅helppause)来保持窗口。
在X环境下,gnuplot如同其他Xclient程序一样,可接受许多参数。如
gnuplot-font8x13bold#设定字形为8x13bold。gnuplot-geometry900x700#设定窗口的长为900pixel宽为700pixel。gnuplot-bgblack#设定背景颜色为黑色。gnuplot绘制数学函数或数值资料的步骤大体如:
定义常数及函数:定义常数及函数,使程式模组化及易于了解。
设定绘图环境:gnuplot绘图之前已预先设定许多绘图参数。
绘图:在定义数学函数或设定绘图环境之后,接着就是绘出数学函数或数值资料的图形。gnuplot提供操作方便的绘图指令——plot(2D)或splot(3D)。
产生输出结果:在终端上绘出结果后,可经由一些步骤而产生不同输出装置所需的输出。
依照上述过程,可快速地画出图形。剩下的步骤就是细心的调整绘图环境参数或修改函数方程式、常数等,即可得到满意的结果。
gnuplot表示数字可分成整数、实数及复数三类:
整数:gnuplot与C语言相同,采用4byte储存整数。故能表示-2147483647至+2147483647之间的整数。
实数:能表示约6或7位的有效位数,指数部份为不大于308的数字。
复数:以{
gnuplot储存数字的原则为,若能以整数方式储存则以整数储存数字,不然以实数方式储存,其次以复数方式储存。例如在gnuplot执行
print1/3*3print1./3*3分别得到0和1.0的结果。这是因前者使用整数计算,而后者采用实数计算的结果。执行
print1234.567print12345+0.56789print1.23e300*2e6print1.23e300*2e8分别得到1234.57、12345.6、2.46e+304和undefinedvalue的结果。这些例子是受到实数的有效位数和所能表现最大数字的限制。这是我们要注意的。
gnuplot的操作符与C语言基本相同。所有的操作均可做用在整数、实数或复数上。
表格1UnaryOperators
Symbol
Example
Explanation
-
-a
unaryminus
~
~a
one'scomplement
!
!a
logicalnegation
a!
factorial
表格2BinaryOperators
**
a**b
exponentiation
*
a*b
multiplication
/
a/b
division
%
a%b
modulo
+
a+b
addition
a-b
subtraction
==
a==b
equality
!=
a!=b
inequality
&
a&b
bitwiseAND
^
a^b
bitwiseexclusiveOR
|
a|b
bitwiseinclusiveOR
&&
a&&b
logicalAND
||
a||b
logicalOR
:
ab:c
ternaryoperation
在gnuplot中函数的参数可以是整数,实数或是复数。表格3是gnuplot所提供的函数。
表格3gnuplotfunctions
Function
Auguments
Returns
abs(x)
any
absolutevalueofx,|x|;sametype
complex
lengthofx,sqrt(real(x)^2+imag(x)^2)
acos(x)
1/cos(x)(inversecosine)inradians
Acosh(x)
cosh1x(inversehyperboliccosine)inradians
arg(x)
thephaseofxinradians
asin(x)
1/sin(x)(inversesin)inradians
asinh(x)
sinh1x(inversehyperbolicsin)inradians
atan(x)
1/tan(x)(inversetangent)inradians
atan2(y,x)
intorreal
tan1(y/x)(inversetangent)
atanh(x)
tanh1x(inversehyperbolictangent)inradians
besj0(x)
J0Besselfunctionofx
besj1(x)
J1Besselfunctionofx
besy0(x)
Y0Besselfunctionofx
besy1(x)
Y1Besselfunctionofx
ceil(x)
smallestintegernotlessthanx(realpart)
cos(x)
radians
cosx,cosineofx
cosh(x)
coshx,hyperboliccosineofx
erf(x)
Erf(real(x)),errorfunctionofreal(x)
erfc(x)
Erfc(real(x)),1.0-errorfunctionofreal(x)
exp(x)
exponentialfunctionofx
floor(x)
largestintegernotgreaterthanx(realpart)
gamma(x)
Gamma(real(x)),gammafunctionofreal(x)
ibeta(p,q,x)
Ibeta(real(p,q,x)),ibetafunctionofreal(p,q,x)
inverf(x)
inverseerrorfunctionofreal(x)
igamma(a,x)
Igamma(real(a,x)),igammafunctionofreal(a,x)
imag(x)
imaginarypartofxasarealnumber
invnorm(x)
inversenormaldistributionfunctionofreal(x)
int(x)
real
integerpartofx,truncatedtowardzero
lambertw(x)
LambertWfunction
lgamma(x)
Lgamma(real(x)),lgammafunctionofreal(x)
log(x)
ln(x),naturallogarithm(basee)ofx
log10(x)
log(x),logarithm(base10)ofx
norm(x)
normaldistribution(Gaussian)functionofreal(x)
rand(x)
real(x)
Rand(real(x)),pseudorandomnumbergenerator
sgn(x)
realpartofx
sin(x)
1ifx>0,-1ifx<0,0ifx=0.imag(x)ignored
sinh(x)
sin(x),sineofx
sqrt(x)
sinh(x),hyperbolicsinex
tan(x)
sqrt(x),squarerootofx
tanh(x)
tan(x),tangentofx
column(x)
int
columnxduringdatafilemanipulation.
defined(X)
variablename
returns1ifavariableXisdefined,0otherwise.
tmhour(x)
thehour
tmmday(x)
thedayofthemonth
tmmin(x)
theminute
tmmon(x)
themonth
tmsec(x)
thesecond
tmwday(x)
thedayoftheweek
tmyday(x)
thedayoftheyear
tmyear(x)
theyear
valid(x)
testvalidityofcolumn(x)duringdatafilemanip.
下面举一些例子:
plot[0.5:20]besj0(x),besj1(x),besy0(x),besy1(x)plot[0:5]erf(x),erfc(x),inverf(x)
在gnuplot中,用户可自定函数。函数可有1至5个自变量。其定义函数的语法如下:
而用户定义常数的语法如下:
gnuplot已定义的常数仅有pi(pi=3.14159)。
如第二章所述,只要键入plotsin(x),'1.dat'即可得到图1的结果。gnuplot自动调整X轴、Y轴的显示范围,使图形显示在适当的位置并选择不同的颜色、图形,用以区别不同的函数或数据,也就是gnuplot自动调整其所需的绘图环境。若我们需要一些特别的绘图参数,如在3D中加入等高线、设定消去隐藏线、改变X轴、Y轴的座标点名称等,可由改变绘图环境参数而改变之。本章说明这些绘图参数设定的方法与功能。
绘图参数在设定坐标轴方面的参数可分为变量名称、数字格式、网格、显示范围、坐标轴显示方式与显示与否等六方面的设定:
一般以x为横轴上的变量。可用dummy设定为其它的名称,所绘函数的变量名称亦随之改变。如setdummyt将自变量改为t,图8、图17、图20均改变自变量名称。
设定数字的显示方式与格式。由format此项参数设定显示格式,其语法为:
setformat{
setformatxy"%.2e"setformatx"%3.0fcm"显示方式由tics、xtics等设定。
xtics是对X坐标轴上的格点做设定。如起始点、结束点、间隔或在轴上特定点放特定的名称。其语法为:
setxtics{{
xdtics将X座标轴上标点名称依0,1,…改为Sun,Mon,…Sat等。大于7的数目除以7取其馀数。
ytics,ymtics,ydtics,ztics,zmtics,zdtics与xtics,xmtics,xdtics相似,不同点是作用在不同的轴上。
ticslevel是在画3D图形时,调整Z轴的相对高度。语法为:
setticslevel{
分为线性与对数两种。一般为前者,若要改为对数方式,其语法为:
setlogscale
改变各轴的显示范围。autoscale参数设定后gnuplot自动调整显示范围。其余的如rrange,trange,xrange,yrange,zrange则是由使用者设定该轴的范围,以xrange为例,其语法为:
setxrange[{
setxrange[0:10]plotsin(x)使用autoscale参数调整显示范围,其语法为:
setautoscale
设定是否要画出座标轴,以X轴为例:
setxzeroaxis#设定显示X座标轴setnoxzeroaxis#设定不显示X座标轴showxzeroaxis#检查X座标轴显示与否Labelgnuplot除了绘出图形外,尚可加入注解做为辅助说明。这注解包括文字与线条两方面,其提供的设定有:
功能
绘图参数名称
线条
arrow
文字注解
key,label,time,title,xlabel,ylabel,zlabel
在图上画一线段可以选择有无箭头。其语法为:
setarrow{
settitle{"
标示(label)为在图上任一位置加上文字说明,一般与线条一并使用。其语法为:
setlabel{
#将y=x放在座标(1,2)之处。setlabel"y=x"at1,2#将y=x^2放在座标(2,3,4)之处,并命名为3。setlabel3"y=x^2"at2,3,4right#将名为3的标示居中放置。setlabel3center#删除名为2的标示。setnolabel2#删除所有标示。setnolabel#显示标示使用情形。showlabel一般绘一图形后,gnuplot将函数名称或图形名称置于右上角。key参数设定可改变名称放置位置。其语法为:
setkeysetkey
setkeyat2,0.5plot[-pi/2:pi]cos(x),-(sin(x)>sin(x+1)sin(x):sin(x+1))