E

EdwardWong

V1

2022/09/16阅读:13主题:姹紫

Gnuplot进阶

本文是gnuplot的进阶篇,基础篇可以参考Gnuplot 基础篇.

如何用单行命令执行

gnuplot -e 'command1';'command2';'command3'...

例如gnuplot -e 'set term dumb;plot sin(x)'

set term dumb 可以在终端上绘制ascii字符表示的图标

验证了在linux,mac可以使用,在windows上的cmd不知道为何不行

如果使用gnuplot -e 'plot sin(x)'交互的画图时, 如果只使用-e选项时,弹窗会立刻消失, 此时需要加上-p选项, 并且**-p -e不能颠倒,-pe-ep 都会报错**

执行Gnuplot脚本

gnuplot脚本没有明确的扩展格式,通常可以使用.p,.plt,.gnuplt 作为拓展名

gnuplot -p script.plt

以下是script.plt脚本的内容:

set term dumb

set xrange[0:5]

set xtics 0,1,5

plot x

文件分隔符

gnuplot默认以空格作为数据分隔符,当然也可以设置其他的数据分隔符。

  • 以空格为分隔符的数据文件

set datafile seperate " "

  • 以逗号为分隔符的数据文件

set datafile seperate ","

  • tab为分隔符的数据文件

set datafile seperate "\t"

自定义line style, label

set style line 1 lc rgb "#8b0000" lw 2

set style line 2 lc 0 pt 7 ps 0.9
set label 1 'Left' at 0.1,0.55 left front

set label 2 sprintf('%d',ii-181) at 4.8,0.6 right front font 'Verdana, 12'

数据文件中的注释

注意是数据文件的注释,而不是脚本文件的注释, 默认是#符号,但必须是该行的第一个字符,否则将不视为注释。注释行被gnuplot直接忽略。

  • 可以查看注释标识show datafile comments

  • 改变默认的comment注释标识 set datafile commentschar "#!"

同时制定了多个符号,表示#!都可以作为注释符号

数据文件中的缺失值

默认情况下,空白被当成是分隔符,这里需要指定缺失值 set datafile missing "NAN"

plot命令对于缺失值的处理有两种方式

plot "datafile" using 1:2 w lp   # continuous

plot "datafile" using 1:($2) w lp # discontinuous

第一种方式是直接忽略缺省值但依旧有直线相连,第二种方式虽然也是忽略缺省值,但缺省值前后不相连

字符串及字符串操作

  1. 合法的字符串
a='this is a string'
b="First line\nSecond line"
c="Double quote\" escaped"
d='string quote'' escaped'

这里说明一下,命令中的字符串和数据文件中的字符串是两码事,不要弄混了。 注意在单引号中是不能识别转义符()的,在双引号表示的字符串中出现双引号时使用转义符**,而在单引号表示的字符串中出现单引号时要用两个单引号转义**。

  1. 字符串操作

整数可以隐式的转成字符串,数字格式的字符串也可以隐式的转成数字。

x = '3.14'
y = x + 2 # y=5.14
a = 4
b = a."foo" # a should be integer

字符串也有比较运算符

c = a eq b ? "same":"different"   # is equal
d = a ne b ? "different":"same" # is not equal

gnuplot中的字符串同样可视为一个字符数组,与其他语言不同的是,第一个字符的下标是1,而不是从0开始

a = "Gnuplot"
b = a[2:3] # b = "nu"
c = a[2:] # c = "nuplot"

d = a[:4] # d = "G

还可以自定义字符串函数

head(s) = s[1:3]
a = head("January") # a = "Jan"

其它内置函数:strlen(s), substr("str",i,j), strstrt("str","key"), words("str"), word("str",n), sprintf("format", ...), gprintf("format",...), system("cmd") 其中system函数是执行操作系统的命令。

从数据文件中读取字符串作为标签

这个用法是给每个点指定一个字符串显示在图上,就像是地名一样

因此需要用using指定第三列字符串数据,当然这三列也可以用其他方法生成,比如stringcolumn函数

plot "datafile" using 1:2:3 with labels

plot "datafile" using 1:2:(stringcolumn(2)) with labels

stringcolumn(N)和column(N)函数一样,都是得到当前行第N列的数据,只不过前者返回一个字符串,后者返回一个数。

使用index

index {int:start}[:{int:end}][:{int:step}] //其中{}表示必须选项,[]表示可选选项

下面是数据文件:

gnuplot -e 'set term dumb;plot "index.dat" index 0 using 1:2 with lp'

注意数据集文件分组用两行空行区分,数据集的分组从0开始。

gnuplot -e 'set term dumb;plot "index.dat" index 1:2 using 1:2 with lp'

gnuplot -e 'set term dumb; plot "index.dat" index 0:2:2 using 1:2 with lp'

使用every

every{int:step}[::{int:start}[::{int:end}]] // 使用两个冒号

gnuplot -e 'set term dumb;plot "every.dat" every 2 using 1:2 with lp' //every 2后面start行号默认缺省

gnuplot -e 'set term dump;plot "every.dat" every 2::1 using 1:2 with lp'

动图

画动图可以分为两种,一种是直接输出很多张照片,然后用某些flash软件合成,另外就是直接用gif输出

有公式的绘图

需要在gnuplot里面用到循环。

首先编写一个plotfunction.plt文件

set term gif animate delay 10 size 600,400 // 设置图片大小及时间间隔

set title 'the sin(x/3)exp(-4x) picture' font 'Times,25'

set output "sinx_exps.gif"

set xlabel 'x' font 'Times,25'

set ylabel 'y' font 'Times,25'

set size 1,1 //设置缩放比例

set xrange[0:8*pi]

set yrange[-1:1]

unset key

i=1

load 'loop_sinx.plt'

set output #导出

上面调用了loop_sinx.plt文件,文件内容为:

plot sin(x/3+i*pi/5)*exp(-x/4) with lines lw 3

i=i+1
if (i<40) reread # 若不满足

直接在终端调用load 'plotfunction.plt'即可。

没有公式的绘图

可以从数据点绘制,并且只要好好的安排数据点的 排序以及用好every等命令,就可以画出很多有意思的图形。

  • 示例1
set term gif animate delay 20 size 960,960
set title 'the sin and cos'
set output "animate3.gif"
set xlabel 'x'
set ylabel 'y'
set zlabel 'z'
set xrange [-1:1]
set yrange [0:20]
set zrange [-1:1]
unset key
i=1
load 'looper1.plt'
set output

其中looper1.plt的内容为:

splot      'spiral.txt' every ::i::i with points pointsize  6 pointtype 7
#这里every的::i::i画出来是一个点,如果要画线用到every 1::0::i
i=i+1
if(i<100) reread
  • 示例2
set term gif animate delay 20 size 500,700
set title 'the wave guide'
set output "animate4.gif"
set xlabel 'x'
set ylabel 'y'
set zlabel 'z'
#set xrange [40:120]
set yrange [40:120]
set zrange [-160:180]
unset key
i=6420
load 'looper1.plt'
set output

循环文件looper1.plt内容为:

splot      'wave.txt' every 1::6419::i with linespoints pointsize  1 pointtype 1
set hidden3d ## set hidden3d 可以
i=i+120
if(i<19200) reread
  • 示例3 轨迹图
do for[ii=1:99]{
splot 'spiral.txt' every ::1::ii w l ls 1,\
splot 'spiral.txt' every ::ii::ii w p ls 1
}

如果想要反方向的话运动的话,只需要修改for循环里面的条件为do for [ii=99:1:-1]即可。

  • 示例4 波动图

产生上述图片的代码如下:

#!/usr/bin/gnuplot
reset
set terminal pngcairo size 350,200 enhanced font 'Verdana,10'

# color definitions

set style line 1 lc rgb '#0060ad' lt 1 lw 1.5

## 设置border
set style line 101 lc rgb '#808080' lt 1

set border 0 back ls 101

set tics out nomirror scale 0

set format ''

# 设置grid

set style line 102 lc rgb '#ddccdd' lt 1 lw 0.5

set grid xtics ytics back ls 102

unset key

set xtics 0.1 //x的刻度间隔是0.1

set ytics 0.15

set xrange[0:4.8]

set yrange[-0.75:0.75]

set lmargin screen 0.02

set rmargin screen 0.98

do for[i=1:360]{
set output sprintf('hrir_frame%03.0f.png',i)
set multiplot layout 2,1
set tmargin screen 0.95
set bmargin screen 0.60
set label 1 'Left' at 0.1,0.55 left front
set label 2 sprintf('%d',ii-181) at 4.8,0.6 right front font 'Verdana 12'
plot 'ir.txt' u($1*1000):2*ii w l ls 1

## 画下面的图
set tmargin screen 0.55
set bmargin screen 0.2
set label 1 'Right'
unset label 2

# x axis

set arrow from 0,-1.3 to 4.8,-1.3 nohead front
set for[jj=0:4] arrow from jj,-1.35 to jj,-1.25 nohead front ls 101
set for [jj in '0 2 4' label jj,'ms' at jj-0.05,-1.1 front tc ls 101
plot `ir.txt` u ($1*1000):2*ii+1 w l ls 1
unset arrow
unset label
unset multiplot
}

# create movie with mencoder
ENCODER = system('which mencoder');
if (strlen(ENCODER)==0) print '=== mencoder not found ==='; exit
CMD = 'mencoder mf://*.png -mf fps=25:type=png -ovc lavc -lavcopts vcodec=mpeg4:mbd=2:trell -oac copy -o hrir.avi'
system(CMD)

# Create webm
ENCODER = system('which ffmpeg')
if (strlen(ENCODER)==0) print '=== ffmpeg not found, exit ==='; exit
CMD = 'ffmpeg -i hrir.avi hrir.webm'
system(CMD)

一些其他比较有趣的动图可以参考动图示例

图形显示时的热键

分类:

后端

标签:

后端

作者介绍

E
EdwardWong
V1