用gnuplot绘制你的数据

gnuplot
用gnuplot4.0可以将你的数据和函数变成看上去专业的图片。gnuplot是一个自由分发的绘图软件。本文给出一个方便的gnuplot指南,重点是一些术语,能帮助你高效地使用这个工具。

gnuplot是一个自由分发的绘图工具,已经被移植到几乎所有的主要系统上。它有两种工作模式:当你需要调整和美化一幅图使之正确,你可以用交互模式操作它,也就是在gnuplot提示符后输入命令。另外,gnuplot可以从文件中读取命令,以批处理的方式产生图片。例如,如果你要做一系列的实验,并且需要在每次实验后观察实验结果的图片;或者,当你修改一张你很久以前做的图片的某一部分时,批处理模式就特别有用。因为,你在所见即所得编辑器里美化图片时捕捉鼠标点击很困难,但你可以很容易地把gnuplot命令存入一个文件,并在6个月后在交互方式下重新执行。

gnuplot最早由Colin Kelley 和Thomas Williams开发于1986年。一些贡献者为其添加了不同的“终端”支持产生不同的变种。在1989到1990年间,这些被融入 gnuplot2.0。2004年4月,4.0版发布。这个教程是用于4.0版的,但这里介绍的大部分命令也可以用于其它版本。可能的情况下,我会提到那些主要的区别。gnuplot的官网列在资源里。

下面,我们给新手一个方便的教程;但即使你有gnuplot使用经验,你也可能会发现出现的4.0版的新术语和新命令。我们从一个简单的sin函数曲线开始并且按照我们的需要进行定制。接着我们将学习如何画一系列的数据点。本文,我们只讨论2D绘图,因为这是最一般的情况。

 
GNG:gnuplot不是GNU
虽然名字有所暗示,gnuplot不使用GPL。对于法律上的好奇,gnuplot的FAQ #1.7说:“gnuplot是在你免费使用意义上的自由软件。但你不能自由发行你自己修改的版本。请阅读并接受你那版的版权文件。

经常,新手用户可能对他们图片可能的外观有很好的想法,但明显不是他们需要使用的gnuplot命令。所以理解gnuplot的关键是很好掌握它的单词表,并且能本能地使用它们。这个教程里,我只能提供给你最终使用gnuplot的一般选项的感觉;这绝对不是彻底的。所以,例如,我告诉你如何设置x-range来限制图片x轴的范围,设置y-range也是类似(使用yrange来代替命令中的 xrange),但我不会再说。


基础
在你的命令提示符后输入gnuplot来打开gnuplot。首先你看到的是提示符>。这个提示符是 gnuplot的输入点;linux用户对此应该很习惯。例如,你可以用方向键浏览你以前输入命令的历史记录,接着可以编辑和重新执行它们,而且, Home键和End键功能如你所想。gnuplot可以在编译时使用GNU readline库,使输入顺序可以变化,但基本功能类似。

如果你想要做些有价值的事情,你就不可避免要使用gnuplot所带的在线帮助。语法是统一的:任何命令的帮助信息都可以通过键入help <command>来得到。来吧,运行gnuplot,并且马上试一下命令help set yrange和help set。一般,gnuplot帮助会提供命令所有可能定制的进一步的帮助信息。看一下帮助中的例子部分会对更好理解如何使用一个命令有所帮助。

gnuplot还带有一大堆演示来显示它的功能,一般放在安装目录的demo文件夹中。要得到这些绝技,在gnuplot提示符下转入这个目录(例如, cd 'd:/gnuplot install/gnuplot/demo'– 注意gnuplot要求所有文件和目录名用单引号或双引号括起来),并且输入load ‘all.dem’。这个目录每个.dem文件演示一个功能,而all.dem一次性加载所有文件。你可能想看完本文后再做这个练习,这样我们的教程不会在更忙乱中开始。

如果想跟着做的话,你可以在提示符下将那些代码一行行输入。另外,可以把代码存入一个临时文件中,并在提示符下输入load ‘filename’来运行它(别忘记引号)。
如你所想,2D绘图命令是plot。输入plot sin(x):你就可以看到一个弹出窗口中熟悉的sine曲线。

图1。sin(x)

<!--[endif]-->

我们刚做了可能是最简单的图。让我们看看如何用不同的方法定制它。现在我们只想要看sine曲线的一个周期。我们限制此图的x-range来做到这一点。范围是用记号[最小值:最大值]来表示的。若只确定最小值,就用[最小值:];若只确定最大值,就用[:最大值]。数学家称这个记号叫闭区间。
这里,我们用[-pi:pi]得到一个正弦曲线周期:

代码1.sin(x)从-pi到pi
set xrange [-pi:pi]
replot
reset
图2.重画的sine曲线图

<!--[if !vml]-->

<!--[endif]-->

我们刚才使用了replot命令,它执行前一个绘图命令。这个命令很有用,当你刚调整了一个图片并且需要继续调整,加入需要的特性时,就用它。另外,replot让你加入更多的图。试一下输入replot cos(x)。句法上,这相当于plot sin(x), cos(x)。replot只是简单地把之前的绘图语句,加上一个逗号,再加上余下的输入部分。

最后一个使用的命令是reset,严格说来,对画sine曲线是不必要的。它清除之前所有set命令的效果,恢复成缺省值。这样,在这个例子里,它使用缺省的x-range。
现在,我们试一下更有趣的东西:plot sin(x)/x。你会看见下面的图:

<!--[if !vml]-->

<!--[endif]-->

就从这三个例子里,可以看出,gnuplot理解pi并且有丰富自然的数学功能词汇表。它甚至知道有用的统计函数正态分布和深奥的特殊函数如lambert, bessel, beta 和 gamma函数(还有更多!)。这些一般只有一些成熟的数学工具如mathematica里才有。经验上,它的语法与C语言的语法类似,也就是说与日常数学的语法类似。(一个重要的例外是幂表达式:x的y次方,习惯地写成x**y)。

接下来,我们给图加个标题(”My First Graph”),坐标轴也一样(x轴是”angle, in degrees”,y轴是”sin(angle)”)。

代码2.给图和坐标轴加标题
set title “My first graph”
set xlabel “angle, \n in degrees”
set ylabel “sin(angle)”
plot sin(x)

注意,xlabel设置串里的\n产生一个换行。一般,gnuplot对双引号字串里的反斜线进行类似C语言的处理。windows的用户需要知道:如果你打算用双引号括住文件名,必须使用双反斜线:例如”c:\\developerworks”(或者,你可以使用正斜线:”c:/developerworks”)。
现在,我们注意到x轴不是用度来标记的并且看上去不怎么样。我们把这些改掉,调整x轴上的标记,只在90度增幅点上标记数字,在45度增幅点上做标记。主要标记是0级别,这是缺省的;次要标记的级别是1。每个标记点分别由一个3-元组定义:”label”(用引号括起来),<要标记的点>,和<可选级>。
代码3.替换坐标轴标记并且设置网格
set xrange [-pi:pi] #我们只要一个周期
set xtics (“0” 0, “90” pi/2, “-90” –pi/2, “” pi/4 1,\
“” –pi/4 1, “” 3*pi/4 1, “” –3*pi/4 1)
set grid
set xlabel “Angle, \n in degress”
set ylabel “sin(angle)”
plot sin(x)

图4.带标记,标题,网格和坐标轴名的sin(x)

<!--[if !vml]-->

<!--[endif]-->

注意,在+/-45度的次要标记处使用了空标题(””)。还可以看出,我们不需要以任何顺序列出标记点。象 gnuplot中的其它命令,xtics很功能很多,并且可以方便地在规则递增点上建立标记(在对数坐标上的多种规则),和为时间相关数据准备的特别格式。更多的内容参考help set xtics中的例子。

另外,请注意我们用反斜线来把xtics命令扩展到多行输入。这可以让长而复杂的命令容易阅读。
我们还用set grid开启了网格,这方便你观察图形数据。前面我们一直在使用set命令。gnuplot有统一的方法取消设置:在gnuplot4.0里,这个命令是 unset。例如,如果你不喜欢网格,就用unset grid。4.0版以前这个命令一直是set nogrid。

顺便说一下,我们给的所有例子都可以在交互模式或批处理模式下运行。交互模式下,在提示符后输入每行命令就可以运行了。批处理模式下,要把命令输入到文本文件中,并且,或者是在gnuplot提示符后使用load ‘filename’读入它,或者是在shell提示符后当作参数传给gnuplot:$gnuplot filename。用第二种方法,gnuplot在执行完输入文件中的所有命令后就会退出,所以在把图形直接绘入文件的情况下,这种批处理方法效率最高(见下一节)。如果第二种方法用在向屏幕绘图中,输出窗口会在绘图一结束就消失(当gnuplot退出时),所以,你需要使用明确的pause –l命令(见help pause)留住窗口。

批处理方式下,gnuplot命令文件会保留一段时间,所以使用注释对增加可读性很有帮助。任何从#到行末间的东西都是注释。所以在代码3里,gnuplot不会处理“我们只要一个周期”。

终端--一个分枝
一开始,你可能注意到终端类型设置成X11。gnuplot是模块化设计并且可以在几种终端设备上绘图。这包括直接打印到几种打印机上,包括Epson,HP 和 Imagen打印机。它甚至能打印到伪设备如postscript和png上。基本上这只产生一个输出文件而不是一个可看的文件或打印输出。这是个把你的图放入其它报告中的窍门。虽然我没有注意到windows和linux上有任何不同,文档建议,你最好在设置输出文件名前设置好终端类型。
代码4.设置输出和终端类型
set terminal png #gnuplot建议设置输出文件名前设置好终端类型
set output ‘output.png’
replot

现在,output.png里是你刚画的图,可以放入一个更大的报告里了。还有些为一些流行的类型设置和绘图程序准备的特殊终端,包括Adobe Illustrator(set term aifm),Corel Draw(set term corel), AutoCad(set term dxf), 和 几种 LaTex相关的终端(eepic, latex, pstricks, texdraw, tpic,等等)。你也可以在PostScript里得到这个文件,用加强的PostScript(eps)或Adobe 的PDF格式。你的gnuplot版本可能没有把所有的终端驱动一起编译进去----例如,windows用户不需要X11终端,而Linux用户不需要 windows终端。类似的,由于法律原因,gnuplot4.0删去了对gif的支持。

所有终端的能力是不同的。一些象LaTeX的不支持文字旋转,所以,如果你设置了ylabel,象我们之前所做的那样,在不同的终端上看到的结果是不同的。别一方面,你可以在确定LaTeX终端的情况下使用LaTeX命令。例如,set ylabel “$sin(\\theta)$” (注意,我们用了双反斜线来产生LaTeX所需要的单反斜线 ---- gnuplot在做了双引号内反斜线处理后才把字串传送给终端驱动)。现在,你可以把你的输出文件使用\input{output.tex}放入你的 LaTeX文件。同样,在PostScript终端里,使用对应的PostScript命令:{/Symbol q}。对加强的PostScript和LaTeX来说,你都可以用标记x^{superscript}和x_{subscript}做上标。还要注意缩写的终端和输出命令:
代码5.eps驱动的功能
set term post enh # enhanced PostScript, essentially PostScript
# with bounding boxes
set out 'gplt.eps'
set xlabel '{/Symbol q_1}
set ylabel 'sin^2({/Symbol q_1})'
plot sin(x)**2
下面资源一节里给的代码里有一个例子TeX文件演示了上面命令的效果。

鼠标支持
到4.0版本,Windows和X11终端都支持鼠标交互。鼠标支持有两个作用:坐标跟踪和缩放。鼠标的当前坐标显示在终端窗口的左下角。它可以用双击鼠标第一键复制到剪贴板上,当你需要放置一个标签或者带有明确坐标的箭头时,这个用处就大了。(使用help arrow和help label查看这些命令的更多细节。)你也可以用鼠标第二键拖动(或右击)选择一个矩形区进行放大。在3D绘图里,你可以拖动鼠标来旋转图像(按住控制仅改变轴的视图;所以,因为图形需要很长时间渲染,你可以先改变轴,然后再放开控制键来重新渲染图形)。
鼠标支持也激活了很多有用的热键:如果你之前放大过图形,用u取消放大图形;g激活网格,l激活两个轴的对数坐标;L激活最接近指针的轴的对数坐标;r激活标尺,可以当做近似的原点。当标尺激活后,窗口底部显示当前鼠标指针位置到标尺原点及标尺原点到原始原点-- --即坐标原点----的x和y向上的距离。在3D图里,方向键可以用在鼠标拖动图形旋转的场合;空格键跳回命令窗口,而q则关闭终端窗口。在鼠标有效的终端窗口里按h可以查看所有的选项。

控制比例和比率
缺省时,gnuplot在x和y轴上都用比例1,但没有去控制图形比率(y轴长度对x轴长度的比)。终端驱动使用缺省的终端比率。比例系数和比率都可以用set size命令来设置,如:

# square is synonymous to an aspect ratio of 1;
# scale y-axis by 2, retain x-axis size
set size ratio square 1,2

终端的能力会限制gnuplot在绘图中成功使用给定的比率。set size也可以用来连接multiplot命令,它用来在同一个输出屏幕或文件中产生多个图形。

画多个曲线

聪明的读者可能已经从前面对replot的注释中猜到,gnuplot可以为你同时画多个曲线。现在我们同时画正弦余弦曲线。简单的绘图命令是plot sin(x), cos(x);要画的图形用逗号分开。如果你没有设定其它东西,gnuplot自动使用两种颜色画出两个图形把他们互相区分开----在象windows 和X11的终端里。单色终端用不同的线型显示图形。你可以从图例asd中看出图形中的哪条曲线是哪条。gnuplot也可以让你选择使用什么样式来画图。

unset xtics # keep all other things simple
plot sin(x) with linespoints pointtype 5, cos(x) w boxes lt 4

图5.多曲线

<!--[if !vml]-->

<!--[endif]-->

你可以用with短语(参见help plot with,如果使用版本4.0,也看看help plotting styles)定义眼花缭乱的细节,确定你希望的曲线的外观。在这个例子里,我们显示两个有用的风格。第一个风格,linespoints,一般在画数据图时使用。它在每个样本或数据点上标记一个点,并用线性插补的方法连接相邻的点。现在,我们添加定义点的类型为5,即选择终端功能里的第五种点。第二个风格,boxes,更适合画柱状数据图。注意我们是如何在cos(x)曲线里缩写with as w。类似的,它是线型的缩写,并且是另外一种终端定义设置,选择终端能绘制的第四种线型。无需多说(什么?你还没试试help plot with?),你可以用pt代替冗长的点类型。如果你打算用同样的绘图风格绘制几条曲线(或者在一条绘图命令里,或者在几条命令里),你可以用一条set 命令设置绘图风格。在gnuplot4.0里,使用set style function linespoints;之前的版本使用语法 set function style boxes。改变数据图而不是函数图风格,就使用set style data linespoints(之前的版本用set data style linespoints)。

 
gnuplot是如何做到的
作为一个有趣的方面,这个练习揭示了gnuplot实际上是如何画函数图----它对函数采样并在每个采样点上画出样本。一般,它在这些点之间平滑插值;但使用boxes风格强制它使用柱状图,linespoints风格会在每个采样点上标记一个点。把采样率设为10(set samples 10)并重绘,就可以更清楚看到这一点。(事后把采样率设回为缺省的100)

with短语是我们用的第一个set之外的来定制图形的例子。其它一些常用的选项也可以直接在绘图命令中设置。例如,你也可以用plot [-pi:pi] sin(x)设置xrange。使用这类语法可以快餐式单次性改变缺省绘图选项。要多图绘制或多绘图命令中重复使用,就应该用set命令。
当画两条或更多曲线时,我们需要图例asd来区分它们。缺省情况下,图例在右上角,但如果它干扰了你的图形,你可以把它放在别的地方----如果你愿意,甚至可以在图外。下面的代码片断把图例放在左上角,并用一个框围住。我们还修改了图例中的曲线名,在绘图命令中定义了名字。命令中的title可以缩写为t,象我们在画余弦曲线中所做的一样。如果你不想在图例中命名曲线,使用notitle代替title。最后一点,经常折磨新手的一个问题,就是如果有名字的话,一定要放在with短语的前面:
代码6.定制图形的图例
set key top left
set key box
plot [-pi:pi] sin(x) title "sinusoid" with linespoints pointtype 5, \
cos(x) t 'cosine' w boxes lt 4

图6.定制图例

<!--[if !vml]-->

<!--[endif]-->

在同一屏幕上画相关的图形
上面,我们在同一图形里画正弦和余弦曲线。gnuplot也允许你在同一输出屏幕或文件里画多个并列的图。在一些排版系统里,引用一个文件里的多图比分别引用它们要容易。

现在用一个简单注释的multiplot例子来说明,分别画出正弦,余弦和它们的倒数曲线。基本方法是将屏幕或图形文件边框比例设置为1。接着,我们画这些不同的曲线让它们分别占据四分之一的屏幕。我们也用设置屏幕原点坐标的办法控制曲线显示的位置(参看help coordinates中有关不同坐标系统的讨论)。也要注意,每次绘制都是自动计算轴的宽度,标注等等----所以,你可能需要修改空白宽度来对齐不同的图。在这个例子里,我必须设置左边距为6字符宽,以容纳cosec(x) = 1/sin(x)用科学计数法的标注。

代码7.多图示例
set xrange [-pi:pi]
<!--[if !supportEmptyParas]--> <!--[endif]-->
# Uncomment the following to line up the axes
# set lmargin 6
<!--[if !supportEmptyParas]--> <!--[endif]-->
# Gnuplot recommends setting the size and origin before going to
# multiplot mode
# This sets up bounding boxes and may be required on some terminals
set size 1,1
set origin 0,0
<!--[if !supportEmptyParas]--> <!--[endif]-->
# Done interactively, this takes gnuplot into multiplot mode
# and brings up a new prompt ("multiplot >" instead of "gnuplot >")
set multiplot
<!--[if !supportEmptyParas]--> <!--[endif]-->
# plot the first graph so that it takes a quarter of the screen
set size 0.5,0.5
set origin 0,0.5
plot sin(x)
<!--[if !supportEmptyParas]--> <!--[endif]-->
# plot the second graph so that it takes a quarter of the screen
set size 0.5,0.5
set origin 0,0
plot 1/sin(x)
<!--[if !supportEmptyParas]--> <!--[endif]-->
# plot the third graph so that it takes a quarter of the screen
set size 0.5,0.5
set origin 0.5,0.5
plot cos(x)
<!--[if !supportEmptyParas]--> <!--[endif]-->
# plot the fourth graph so that it takes a quarter of the screen
set size 0.5,0.5
set origin 0.5,0
plot 1/cos(x)
<!--[if !supportEmptyParas]--> <!--[endif]-->
# On some terminals, nothing gets plotted until this command is issued
unset multiplot
<!--[if !supportEmptyParas]--> <!--[endif]-->
# remove all customization
reset

图7.多图绘制

<!--[if !vml]-->

<!--[endif]-->

绘制数据
虽然本文大多数情况下,为了说明目的,集中讨论正弦曲线的绘制,但你可能最想画来自实验或销售或类似的数据。这一节,如何画不同的使用IBM股价作为数据集的图(这个例子的原始数据放在资源那节):
表1.IBM股价
Date Open High Low Close
10-Jun-04 90.23 90.75 89.89 90.46
9-Jun-04 89.90 90.55 89.81 90.09
8-Jun-04 88.64 90.50 88.40 90.04
7-Jun-04 88.75 88.99 88.01 88.64
4-Jun-04 87.95 88.49 87.50 87.56
3-Jun-04 87.85 88.10 87.35 87.35
2-Jun-04 88.64 88.64 87.89 87.98
1-Jun 04 88.00 88.48 87.30 88.120
大多数数据集都是数字集,但这一个不同,x轴是时间数据。下面的曲线告诉gnuplot如何读取和格式化x 轴上的时间数据(参看help time/data和help set timefmt以获得更多细节):
代码8.设置时间序列数据
set xdata time # The x axis data is time
set timefmt "%d-%b-%y" # The dates in the file look like 10-Jun-04
set format x "%b %d" # On the x-axis, we want tics like Jun 10

设置好后,我们可以用下面的命令画开盘价。我们选择在不同的开盘价间使用直线插值,并使用linespoints风格而不仅是points风格:

plot ["31-May-04":"11-Jun-04"] 'ibm.dat' using 1:2 with linespoints

图8.IBM股价图

<!--[if !vml]-->

<!--[endif]-->

和前面一样,明确设置xrange["31-May-04":"11-Jun-04"],但这也不是严格必须的。注意,区间里的最小最大值要定义成timefmt中一致的字符串。

依赖于所用的绘图风格,gnuplot在画一个点时,可以用到最多6个不同的数字。当一个记录被读入,那列数据被标记为从1开始。using 1:2告诉绘图命令使用第一列作为x轴和第二列作为y轴。所以,要画收盘价,我们就得使用using 1:5。

gnuplot每读到一个新数据分隔符就增加列数据字。缺省分隔符是空白符。所以,如果我们的时间格式中间有一段空白(例如,10 Jun 04而不是10-Jun-04),我们需要使用1:4而不是1:2。对x轴,我们只需要定义第一列,数据从那里开始。gnuplot有足够的智能使用时间串去读其它列。

你可以用using添加多于2个冒号来定义额外的数据列,这可能是一些绘图风格所必须的。你也能用使用了$n表示第n列数据的声明表达式绘图。在这个完全虚构的例子里,我们假设不同的价格代表一次不同的实验,并且我们想绘制平均数,最高值和最低值。你可以用 yerrorbars风格绘制y-high/y-low值,这里我们在using修饰语句里定义为x:y:ylow:yhigh,并用($2+$3+$4 +$5)/4来计算的4个价格的平均数作为y轴:
plot ["31-May-04":"11-Jun-04"] 'ibm.dat' using 1:($2+$3+$4+$5)/4:4:3 \
title 'daily prices, IBM' with yerrorbars

图9.计算平均值

<!--[if !vml]-->

<!--[endif]-->

errorlines风格类似,但它在画了的y点之间也画线段。gnuplot还专门有一个风格用来画经济数据条的,有最高最低值还有左右的小标记来分别标记开盘收盘价。我们使用set bars来显示开盘收盘价的大标记:
set bars 5
plot ["31-May-04":"11-Jun-04"] 'ibm.dat' using 1:2:3:4:5 with financebars

图10.画经济数据条

<!--[endif]-->

你还可以查询help plotting styles,查看其它相关风格,象是candlesticks, boxerrorbars和error风格。

处理真实生活中的数据集

当然,真实生活中的数据集里问题更复杂。用非空白符分隔数据点的数据集很常见。作为gnuplot4.0的新功能,你可以用set datafile separator <string>来设置你自己的分隔符。类似的,你也可以定义一个注释符来代替#,用命令set datafile commentschar。如果你需要更多控制,你可以为using修饰短语明确定义一个格式串。gnuplot根据所给的格式串(参看help using了解所有细节),用C语言标准库函数scanf的方式读数据。我仅仅是为了完整性而提起这个方法的,大部分可以用这种方法读入的数据集,也可以使用set data file separator或明确定义using短语中的列数字来处理。例如,如果你在第一列有一个需要忽略,用plot using 2:3就行了。为了完整的柔性,在带有popen函数的类UNIX系统里,你可以使用文本处理工具预处理文件后再传给绘图命令。例如:plot "< awk --f preprocess.awk data.file"。不幸的是,这种方式不适合所有系统。最后一个手段是明确预处理输入文件,再在gnuplot中使用。

有时,真实生活中的数据集可能不包括所有数据点----可能有一个x值,但对应的y值在你准备绘制的那列可能丢失了。gnuplot允许你定义一个字符串来表示丢失数据点。例如:

set datafile missing 'NaN' # The IEEE floating point not-a-number

注意,4.0版之前,这个命令是set missing <string>。

不幸地,丢失数据的数据点处的处理与using设定相关。如果你想知道使用plot 'file', plot 'file' using 1:2, 和 plot 'file' using ($1):($2))之间区别的详细细节,请参看help using。但安全起见,定义数据列时请坚持使用明确的using格式,并且,如果你想完全删除坏数据点,不要使用表达式评价(因为括号,第三个选项评价表达式)---- 而预处理数据文件和增加明确的表达式计算结果数据列更好些。

还有时,你数据集的结束数据可能无效。如果能通知gnuplot无效的数据点,你仍然可以画出此数据集。 gnuplot只是安静地忽略未定义点,所以有个小技巧,当你遇到不合适的点就使用一个未定义的象1/0之类的y值。象C语言中的三重操作符来表达这种情况非常方便(如果你对这个函数不熟悉,请参看help ternary;它在分段函数定义中也很有用)。这里有一个在help using中提到的例子,让你把第二列数据当作y值画出,除非第三列大于10:

plot 'file' using 1:($3>10 ? $2 : 1/0)

一个高级例子
虽然本文已经展示了大部分你最终会常用的功能,偶尔,你需要做些更深奥的东西。这一节,我们简要地讨论一些这方面的内容,接着引用一段来自gnuplot演示文件中的脚本(electron.dem),它画了一条在电子器件用途演示中常见的幅频响应曲线。
1.用户定义函数和变量

你可以定义自己的任意复杂的函数,类似下面提到的A(jw)。它可以带参数(p1, p2),而且,你可以稍后再定义这些参数,只要在绘图命令使用它们之前就行。

2.复数
gnuplot可以理解复数。符号{a, b}代表复数a+bj。你可以用函数abs()和arg()计算模和辐角。
3.哑变量
当你在绘图命令中使用sin(x)时,gnuplot把x作为哑变量使用,给它赋不同的值来得到样本。当你在写复杂的用户定义函数时,你可以在函数定义时用传统变量名,并明确指定该名字用于哑变量(例如,set dummy jw)。
4.x2和y2轴
除了熟悉的图形底部和左边的x和y轴,你还可以使用图形顶部(x2)和右边(y2)作为独立的轴。这些轴是完全独立的,你可以单独设置范围,标记,名字和比例(比如,对数比例)。绘图命令也可以通过使用 axes短语使用不同的轴集象x2y2。缺省情况下,绘图命令在xy轴上工作。当你需要同时绘制级数不同的幅值,或有不同单位的曲线时,这个高级特性就很有帮助。下面的例子里,y轴画幅值,最大为1,而y2轴画相位,最大值为100。如果用同一套轴画,幅值曲线就仅仅能看见而已了。
5.对数比例
你可以用命令set logscale来绘制任何轴为对数比例。这个命令在对应轴上画以10为底的对数值。你可以明确设置要使用的底(例如,set logscale 2, 或 set logscale xy 2,如果只设置主要的x-y轴)。
这就是从gnuplot所带演示文件electron.dem中抽出的片断。这段脚本使用了上面所讨论的所有概念:
代码9.幅频响应
A(jw) = ({0,1}*jw/({0,1}*jw+p1)) * (1/(1+{0,1}*jw/p2))
p1 = 10
p2 = 10000
set dummy jw
set grid x y2
set key default
set logscale xy
set log x2
unset log y2
set title "Amplitude and Phase Frequency Response"
set xlabel "jw (radians)"
set xrange [1.1 : 90000.0]
set x2range [1.1 : 90000.0]
set ylabel "magnitude of A(jw)"
set y2label "Phase of A(jw) (degrees)"
set ytics nomirror
set y2tics
set tics out
set autoscale y
set autoscale y2
plot abs(A(jw)), 180/pi*arg(A(jw)) axes x2y2

图11.幅值和相频响应

<!--[endif]-->

结论
本文,我们讨论了使用gnuplot4.0来绘制2D图形的复杂性。虽然,我们触及了大部分使用gnuplot 的重要方面,由于篇幅所限,还有一部分内容我们没能讨论。最重要的省略包括很简单的带参数函数绘制(见help parametric),和极坐标(help polar),到曲线拟合,就是拟合用户定义的曲线到给定的数据集上。曲线拟合是个艺术,需要一整篇的文章来讲述,但查询help fit和beginners_guide and tips子标题来开始。

经常使用的窍门

就如我们所见,gnuplot是高度可定制的。我总结的最后窍门是如何把你的定制用于多个gnuplot会话:定制最主要的命令是set命令。你可以用save set ‘filename’来保存你当前会话里的所有设置;用save var <file>和save func <file>分别保存用户定义的变量和函数。但是在单个绘图命令里使用的定制(例如plot [-pi:pi] sin(x)里的xrange)是无法保存的。这些文件可以用load <file>读回来。gnuplot在启动时也会查询一个叫. gnuplot的文件。它先在当前目录,接着在用户主目录(在Windows里是USERPROFILE目录)查找。如果找到初始化文件,gnuplot 就执行里面的命令。一些用户就用这个设置终端类型和定义常用的函数和变量。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值