gnuplot入门

简介

前阵子需要使用gnuplot,临时学了一下。发现MATLAB的很多画图操作和gnuplot很像,不过gnuplot好像没有句柄这个概念,所以很快可以上手。

本文只是描述一些我前阵子所用到的一些东西,如果要详细的内容可以看官方文档或者马欢的中文博客

综合转载以下文章:

官方网站

输出设置

输出格式

1
2
3
4
gnuplot> help term
Gnuplot supports a large number of output formats. These are selected by
choosing an appropriate terminal type, possibly with additional modifying
options. See `set terminal`.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
gnuplot> set term

Available terminal types:
aifm Adobe Illustrator 3.0 Format
dumb ascii art for anything that prints text
epslatex LaTeX picture environment using graphicx package
gif GIF images using libgd and TrueType fonts
jpeg JPEG images using libgd and TrueType fonts
latex LaTeX picture environment
mf Metafont plotting standard
mp MetaPost plotting standard
png PNG images using libgd and TrueType fonts
postscript PostScript graphics, including EPSF embedded files (*.eps)
pslatex LaTeX picture environment with PostScript \specials
svg W3C Scalable Vector Graphics driver
tgif TGIF X11 [mode] [x,y] [dashed] ["font" [fontsize]]
x11 X11 Window System
... 部分略

ASCII输出

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
gnuplot> set term dumb
Terminal type set to 'dumb'
Options are 'feed 79 24'
gnuplot> plot sin(x)


1 ++---------------***--------------+---***----------+--------**-----++
+ *+ * + * * + sin(x) ****** +
0.8 ++ * * * * * * ++
| * * * * * * |
0.6 ++ * * * * * * ++
* * * * * * * |
0.4 +* * * * * * * ++
|* * * * * * * |
0.2 +* * * * * * * ++
| * * * * * * * |
0 ++* * * * * * *++
| * * * * * * *|
-0.2 ++ * * * * * * *+
| * * * * * * *|
-0.4 ++ * * * * * * *+
| * * * * * * *
-0.6 ++ * * * * * * ++
| * * * * * * |
-0.8 ++ * * * * * * ++
+ ** * + * * + * +* +
-1 ++-----**--------+----------***---+--------------***---------------++
-10 -5 0 5 10

输出文件

  • 输出文件 set output 'filename'
  • 大小 set size m,nm,n为放大、缩小的倍数(相对于当前大小)
1
2
3
4
5
6
7
gnuplot> set t png
Terminal type set to 'png'
Could not find/open font when opening font "arial", using internal non-scalable font
Options are 'nocrop medium '
gnuplot> set output 'test.png'
gnuplot> set size 2,2
gnuplot> plot sin(x) title 'sin',cos(x) title 'cos'

绘图设置

坐标范围

  • 改变坐标范围 set xrange[min:max]set yrange[min:max]
  • 只在本次绘图中有效 plot [xmin:xmax] [ymin:ymax] f(x)
  • gnuplot自动设置 set autoscale
  • 可以只设置x或者只设置y的范围
  • 可以只设置范围上限或者下限 set xrange[min:]

坐标名称

  • 设置名称 set xlabel 'xlabel'set ylabel 'ylabel'
  • 取消名称 unset xlabelunset ylabel

标题

  • 标题 set title 'title'
  • 标题 unset title

曲线标题

  • 曲线标题 plot f(x) title 'title'
  • 放置位置 set key x,y ;x,y为坐标
  • 重置为默认位置 set key default
  • 不显示曲线标题 unset key
  • 曲线标题框 set key box

刻度

1
2
3
4
5
6
7
set title "My first graph"
set xrange [-pi:pi]  # we want only one cycle
set xtics ('0' 0, '90' pi/2, '-90' -pi/2, '45' pi/4,'-45' -pi/4,'135' 3*pi/4,'-135' -3*pi/4)
set grid
set xlabel 'Angle, in degrees'
set ylabel 'sin(angle)'
plot sin(x)

时间坐标

可以使用时间数据作为x坐标:

1
set xdata time

设置x坐标轴为时间数据,对于其他坐标轴也是一样。

默认格式是 “年/月/日”,可以通过命令来修改:

1
set timefmt “%Y-%m-%d”

具体的格式化字串如下:

格式 解释
%d day of the month, 1–31
%m month of the year, 1–12
%y year, 0–99
%Y year, 4-digit
%j day of the year, 1–365
%H hour, 0–24
%M minute, 0–60
%s seconds since the Unix epoch (1970-01-01 00:00 UTC)
%S second, integer 0–60 on output, (double) on input
%b three-character abbreviation of the name of the month
%B name of the month

如果需要取消x轴的时间形式 可以使用命令来重置:

1
set xdata

同时绘制多个函数

  • 用逗号分隔函数:plot f1(x),f2(x),f3(x)...fn(x)

网格

  • 添加 set grid
  • 取消 unset grid

变量

  • 变量名不区分大小写
  • 变量赋值后即存在
  • show variables简写为sh v
1
2
3
4
5
6
7
8
9
10
11
gnuplot> a=1
gnuplot> b=2
gnuplot> sh v


User and default variables:
pi = 3.14159265358979
NaN = NaN
GNUTERM = "x11"
a = 1
b = 2

函数

  • 内置函数,如sin(x),cos(x),log(x)
  • 自定义函数,如f(x)=x*x; plot f(x)
  • show function查看用户定义函数
1
2
3
4
5
gnuplot> sh fu

User-Defined Functions:
ln is undefined
f(x)=x*x

文件绘图

数据文件data内容如下:

1
2
3
4
5
6
10  0.781  0.73  0.963
20 0.281 0.827 0.93
30 0.281 0.257 0.63
40 0.731 0.7 0.3
50 0.481 0.87 0.6
60 0.681 0.57 0.12
  • plot 'data'将自动使用第一、二列数据作为x,y坐标绘图
  • plot 'data' with lines 将点连起来
  • plot 'data' with linespoint 将各点连起来并用符号标记点
  • plot 'data' using 1:3 with linespoint 指定用1、3列作为x、y坐标
  • plot 'data' using 1:($3/3)plot 'data' using 1:($3+$4),分别表示以第三列的3分之一、第三列和第四列的和作为y坐标
  • plot 'data' using 1:(sin($3)) 对某一列使用函数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
gnuplot> plot 'data' with lines


0.8 ++------------+------------+-------------+------------+------------++
* + + + 'data' ****** +
|* *** |
0.7 ++* * * ++
| * * ** **
| * * * ** |
| * * * ** |
0.6 ++ * * ** ** ++
| * * * ** |
| * * ** ** |
0.5 ++ * * ** ++
| * * * |
| * * |
0.4 ++ * * ++
| * * |
| * * |
| * * |
0.3 ++ ************** ++
| |
+ + + + + +
0.2 ++------------+------------+-------------+------------+------------++
10 20 30 40 50 60

gnuplot> plot 'data' using 1:3 with linespoint


0.9 ++------------+------------+-------------+------------+------------++
+ + + + 'data' using 1:3 **A*** +
| **A ** ** |
0.8 ++ ***** * *** ** ++
| **** * *** * |
A** * ** ** |
0.7 ++ * A* ** ++
| * * **|
| * * |
0.6 ++ * ** +A
| * * |
0.5 ++ * * ++
| * * |
| * * |
0.4 ++ * * ++
| * ** |
| * * |
0.3 ++ * * ++
| A |
+ + + + + +
0.2 ++------------+------------+-------------+------------+------------++
10 20 30 40 50 60

gnuplot> plot 'data' using 1:($3+$4) with linespoint


1.8 ++------------+------------+-------------+------------+------------++
+ *******A + 'data' using 1:($3+$4) **A*** +
A****** * |
1.6 ++ * ++
| * |
| * A |
| * ** * |
1.4 ++ * ** * ++
| * * * |
| * ** * |
1.2 ++ * * * ++
| * ** * |
| * ** * |
1 ++ * ***A * ++
| * ******* * |
| A*** * |
| * |
0.8 ++ *++
| *|
+ + + + + A
0.6 ++------------+------------+-------------+------------+------------++
10 20 30 40 50 60

基础

数据文件中的不能随便空行,需要间隔的时候可以使用“#”注释某一行,因为各个空行是有含义的:

  • 单个空行:表示同一个数据集中的不连续处,即单个空行前后的数据,在绘制时不会连起来。

  • 双空行:表示两个数据集的分隔,不同数据集的数据认为是间断的,即使用一条plot语句会对每个数据集各画一条线,而且它们的style都是相同的。

  • 文件一行一个数据条目,一个数据条目里面可以有若干个维度,各个维度之间默认支持可以用空格或制表符隔开。在gunplut的命令里面通过 \$x 来引用。gnuplot会自动生成一个伪列 \$0,它的值从0开始,可以理解为表示每个数据在文件中的行号。然后其他数据依次是\$1、\$2、\$3等。当不做操作而直接引用的时候可以直接写0,1,2等。

引用某个维度的时候需要使用using关键字,例如我要显示文件a.txt中的第一列,可以用:

1
2
3
4
5
plot 'a.txt' using 1

plot 'a.txt' using 0:1

plot 'a.txt' using 0:($1)

其中第二种形式表示用伪列0做x轴,而第一种形式默认使用它做x轴,第三种形式是使用变量引用的形式。

数据格式

有时候由于数据格式的问题(尤其是我们常用的CSV格式),gnuplot会无法读入我们的数据(对于CSV格式只能读入第一列),需要我们手动指定数据的输入格式,具体方法是在using x:x之后加入双引号括起来的格式字符串。

例如:

1
plot 'a.csv' using 1:2 "%lf,%lf"

格式串中的占位符和c语言中一样。(但是不支持%f,即可以理解为没有float而全都是double)。

文件过滤

有的时候不需要使用文件中的所有数据,可以使用一些关键字来过滤一下。注意它们一般要放在using之前,表示先选择了数据再选择数据中的列。

  • index关键字,它用于选择数据集,接收1到3个参数,依次表示起始的数据集号(从0开始),终止数据集号,步长,例如:
1
plot 'a.txt' index 3:10:3 using 1:2 with line

表示画第3、6、9个数据集的数据。

各个数据集内部的数据是一条线,不同数据集是不同的线,但是它们的颜色(style)是一样的。

  • every关键字,它有1个参数,表示每x个数据取一个(从0开始)。

例如:

1
plot 'a.txt' every 3 using 2

表示画0、3、6、9、12、……行的数据
也接受3个参数,表示步长,起始行号,终止行号;注意是用两个冒号隔开而不是1个。

例如:

1
plot 'a.txt' every 3::3::10 using 2

表示画第3、6、9行的数据。

## 操作各个变量

如果需要对某些维度的值进行计算之后,将它的结构作为要显示的值,那么需要使用\$x的形式引用那个列,在using中不能直接让\$x与其他值并列出现,至少要有括号包裹。可以使用函数,或者具体表达式表示某个新的维度。

例如:

1
2
3
plot 'a.txt' using 1:($1*10-$2/3)
#假设已经定义了一个函数fun,它接受3个参数
plot 'a.txt' using 0:fun($1,$2,$1+$2)

常用命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
pwd:(present working directory)当前工作目录

cd :'< directory >'(come directory)到某个目录,<directory>是想要到的目录名

clear:清空输出的图像

exit和quit:退出gnuplot,也可简写为q

pause <seconds>:暂停一段时间,<seconds>为时间,单位为秒

print <var>:其中<var>为变量名

gnuplot> print 'hello\neveryone'hello\neveryone
gnuplot> print “hello\neveryone”helloeveryone
即单引号屏蔽转义符号 '\',而双引号则不会,它将 \n 看成换行,另外还有 \t 表示制表符。

help 获得帮助 ,如 help term可以看到关于terminal的帮助

命令简写

1
2
3
4
5
6
7
8
plot 'file.dat' with lines, 可简写为plot 'file.dat' with  l, 进一步简写为plot 'file.dat' w  l

同理:
plot 'file.dat' with linespoints, 简写为plot 'file.dat' w lp
set terminal简写set term, 进一步可简写为set ter、se t
set output 简写 set out,进一步可简写为se o
show 简写为 sh
show variables简写为 sh v

平滑

在绘图命令最后加smooth关键字后加方法(和with关键字一样),它相当于自带with line命令,但是它和with关键字不冲突,可以在手动指定with选项。

  • unique:先将using选定的数据进行排序(按x),然后消除重复的点(即x相同的点),消除的方法是取平均值。
  • frequency:和unique不一样,frequency对每个x取统计结果,比如将相同x的多个y值进行求和,因此,这个命令可以统计频率,制作直方图。
  • bezier:绘制N阶贝赛尔曲线,N为点数。
  • sbezier:相当于先使用unique排序,消除重复点,然后再使用bezier
  • csplines:先使用unique,然后再画三次样条曲线。
  • acsplines:先使用unique,然后画加权三条样条曲线,权重由using第三个维度指定,即using关键字后面要有3个维度,且权值必须大于0。权值越大越贴近原来的折线,越小越平。

例如:

1
2
3
plot 'a.txt' using 1 smooth bszier
replot 'a.txt' using 1 with impulse
replot 'a.txt' using 0:1:2 smooth acsplines

脚本功能

  • 注释,使用 “#”
  • 很长的行可以用 \\断行写
  • call 'script'在gnuplot环境下调用画图脚本
  • gnuplot script在shell下直接执行画图脚本

运行Linux命令

在gnuplot提示符下也可以运行Linux命令,但必须在相应的命令前面加上!号。例如,假设,很多参数都已经设置好了,但需要对某个数据文件a.dat进行修改后再画图,则可以用如下方式。

1
gnuplot>!vi a.dat

通过这种方式,所有的Linux命令都可以在gnuplot环境里运行。

另外,也可以在gnuplot的提示符后输入shell,暂时性退出gnuplot,进入Linux环境,做完要做的事情后,运行exit命令,又回到gnuplot环境下。

1
2
3
4
5
6
gnuplot>shell
$vi a.f
$f77 a.f
$a.out (假设生成a.dat数据文件)
$exit
gnuplot>plot 'a.dat' w l
一分一毛,也是心意。