E

EdwardWong

V1

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

Gnuplot

Gnuplot 是一个小巧实用的数据处理工具,主要用来绘制2D/3D数据或者函数图像,也包含数学计算和数据拟合等功能。其支持多种不同类型的输出:交互式屏幕终端,直接输出到绘图仪或现代打印机,并输出到多种文件格式(EPS,JPEG,PDF,PNG)

Gnuplot数据文件一般默认用空白符隔开数据,如果数据文件不是这个类型,需要预先处理数据文件,否则可能无法读取

GNUPLOT的安装与基本知识

GNUPLOT的安装

Ubuntu:

sudo apt-get update

sudo apt-get install gnuplot

Mac:

MacPorts项目把很多Linux上的应用程序移植到苹果系统上,其中就包括gnuplot,只需要在苹果电脑上安装MacPorts,之后就能通过port命令安装包括gnuplot在内的各种linux应用程序了。

Windows:

直接到gnuplot官网上下载压缩文件,然后解压执行gnuplot.exe就可以了。

terminal

Gnuplot支持七十多种terminal,可以通过set terminal指令查看支持的terminal列表。

如果想要更换terminal,则可以通过下面指令切换不同terminal.

set term x11 //这是默认的终端模式

set term post eps color solid enh //矢量模式常用的terminal,输出的图形为psepspost表示postscript模式,默认输出ps格式,可以指定eps,这样会输出eps格式, color表示输出图形为彩色,不用就会保存为黑白的,solid表示输出图中的所有线用实线,不用则表示除了第一条为实线外,其余的均用不同的虚线,使用enh可以在图中插入上下标、希腊字母和特殊字符。

set terminal jpeg //输出为jpeg格式

set terminal png size 800,600 //指定图片大小

有时候png可以使用pngcairo terminal,使用png terminal时,即使图像放大2倍,但是字体大小不会发生变化。

Gnuplot内置的函数

Gnuplot的线型,点型

线型 (linetype)

点型 (pointtype)

with选项后跟的内容

gnuplot中常见的颜色配色

关于颜色的配置,可以参考gnuplot颜色

Gnuplot 的基本命令

set 命令

set命令可以用来设置环境变量,unset用于取消某个环境变量,reset用于全部重置环境变量。以下列出了常用的一些环境变量

set term emf //保存为emf格式,这样图是矢量图,放大或者缩小不会失真

set output "**.emf" //图片保存的名字

set grid //设置图片为网格的形式

设置图形大小和位置

set size 0.5,0.5 % 长度均为默认宽度的一半,建议用这个取值,尤其是画成pseps图形时。

set origin 0.0,0.5 //设定图的最左下角的点在图形面板中的位置,这里图将出现在左上角

设置图形间距

set l(r)margin 15 //设置图片到左边缘的距离

set t(b)margin 3 //设置图片top处边缘的距离

set tmargin screen 0.95

设置图形刻度及范围

set xrange [m:n] // 设置x方向的范围

set yrange [m:n] //设置y方向的范围

set xtics 0.05 font "Times New Roman, 20" offset -0.5,-0.5 //x轴的主刻度宽度为0.05,字体和位置

set mxtics 3 //x轴上每个主刻度中画三个分刻度

set xtics nomirror //将最上面的轴的刻度去掉

也可以对上边的轴x2 和右边的y轴y2进行设置,即x2tics mx2tics y2tics my2tics

unset x2tics //去除上边x2轴的刻度

unset y2tics //去除右边y2轴的刻度

set ytics 2 font "Times New Roman, 20"

set xtics format '' //保留刻度线但是刻度没有

set xtics rotate by 90 //x刻度旋转90度

设置图形标签

set xlabel "****" font "Times New Roman,20" //x方向的名字

set ylabel "****" font "Times New Roman,20" //y方向的名字

set xlabel "*****" offset -0.5,-0.5 //x方向名字的位置

set ylabel "******" offset 0.0,0.0 //y 方向名字的位置

图例位置

set key box //将图例放进方框中

set key left //放在左边,有leftbottom

set key bottom //放在下边,只有一个选项,默认在上边

set key outside //放在外边,但只能在右面的外边

上面三个选项可以进行组合。如:

set key left bottom //图例在左下

set key 0.5,0.6 //精确用坐标表示图例的位置,此时放在坐标0.5,0.6的位置。

set key right top font "Times New Roman,20" spacing 1.5 height 0.8 //图片中对线段类型的标记位置:top(最上面), right(右边)

set sample 100

plot "数据文件1" title "数据1" w lp lt 3 lw 2 "数据文件2" title "数据2" w lp lt 4 pt 10 lw 2

set output //输出到文件中

设置图形边框

set border //设置外围边框

set border 3 lt 3 lw 2 //设置第三种边界,颜色类型为2,线宽为2

set noborder //除去最上边和最右边的图形边框,这个语法已经过时了,可以使用unset border

在图中插入文字

set label 'sin(x) at 0.5,0.5' //在坐标(0.5,0.5)处加入字符串sin(x)

当输出为.ps(矢量图).eps(矢量图)文件时,如果在set term的语句中加入了enhanced 选项,则可以插入上下标、希腊字母和特殊符号,上下标的插入和latex中的方法是一样的。

在途中添加直线和箭头

set arrow from 0.0,0.0 to 0.6,0.8 % 从(0.0,0.0)到(0.6,0.8)画一个箭头

set arrow from 0.0,0.0 to 0.6,0.8 lt 3 lw 2 % 这个箭头颜色类型为3, 线宽类型为2.

set arrow from 0.0,0.0 to 0.6,0.8 nohead lt 3 lw 2 % 利用nohead可以去掉箭头的头部,这就是添加直线的方法。

对于插入多个labelarrow的情况,系统会默认按先后顺序分别对各个labelarrow进行编号,从1开始,如果以后要去掉某个label或者arrow,那么只要用unset命令将相应的去掉即可,如:

unset arrow 2 //去掉第二个箭头

设置零轴

set xzeroaxis // 添加x=0的线

set yzeroaxis //添加y=0的线

set zeroaxis //同时添加x=0和y=0的线

set yzeroaxis lt -1

做二维图时,使两边坐标轴的单位长度等长

set size square       //使图形为方的

set size 0.5,0.5 

set xrange[-a:a]

set yrange[-a:a]    //两坐标轴刻度范围一样

plot `a.dat`

plot命令

plot "{file_name}" using ($1):($2) //利用文件画图,文件一定要使用双引号

plot sin(x) with line linetype 3 linewidth 2 或者plot sin(x) w l lt 3 lw 2

plot sin(x) w p pt 3 ps 2 // 用点画图,点的类型是3,点的大小是2

plot sin(x) title 'f(x)' w lp lt 3 lw 2pt 3 ps 2 //同时用点线画,这里的title表示图例上标f(x), 如果不用则用默认选项

plot 'a.dat' u 2:3 w l lt 3 lw 2 //利用数据文件a.dat中的第二列和第三列画图

plot sin(x) title 'sin(x)' w l lt 1 lw 2, cos(x) title 'cos(x)' w l lt 2 lw 2 //同时画多条曲线,其中曲线之间的选项命令使用逗号隔开,同样可适用于文件,但要用单引号。

plot [-pi:pi] sin(x) title 'sinusoid' with linepoints pointstype 5, cos(x) t 'cosine' w boxes lt 4 //可以在画的同时指定x的范围

plot 'data.dat' using 1:2:($3/1000) title 'my data' lt 7 lc 0 with errorbars, sin(x) lc 7 title "Model1" //第一列为x,第二列为y,第三列为误差值一列,是用标准差表示的,也可以使用最大值和最小值来表示,那么这个时候就需要四列。

上述第一个图用的是xerrorbars,第二个图用的是xerrorlines.两张图都是使用最大值最小值来画errorbar.

plot "data.dat" using 1:2 with lines,"data.dat" using 1:3 with boxes

plot "data.dat" using 1:2 title "data-1" with lines,"" using 1:3 with boxes // 第二个及之后的数据和第一个数据来源相同时,可以只使用双引号""表示

参数画图

set parametric
plot cos(t),sin(2*t+1) w l    //二维
set parametric
splot sin(u)*cos(v), sin(u)*sin(v), cos(u)   //三维
set isosample 100
replot

极坐标图

set ploar
plot cos(t)*sin(t),sin(t) w l

循环画图

plot for[1:10] sin(n*x)

直方图

频率直方图

plot "out.dat" with boxes lt 6 title "frequencey"

其中out.dat的数据如下图:

set xlabel "Data Points"
set ylabel "Frequency"
set title "Histogram of data"
Min=-3.9142
Max=3.5475
n=10            //需要多少个分组
width=(Max-Min)/n
hist(x,width)=width/2+width*floor(x/width)    //判断x在哪个范围    
plot 'uniform.dat' u (hist($1,width)):($2) smooth freq w boxes lc rgb(边框颜色) "red" notitle    //第二列作为`xlabel`
set style data histogram        //设置图表类型为直方图
plot 'score.txt' using 2:xticlabels(1)/xtic(1) title columnheader(2), 'score.txt' using 3:xticlabels(1) title columnheader(2), 'score.txt' using 4:xticklabels(1) title columnheader(3)          // using 2:xticlabels(1) 表示使用第2行的数据作图, xticlabels(1)表示使用第2列的第一个数据作为数据图例名称。

set style histogram clustered gap 1          //柱簇之间的距离是一个柱的宽度。

set boxwidth 0.8 (set boxwidth 0.8 relative or set boxwidth absolute)        // 柱子之间的间距会变小,柱子间出现间隙。

set style fill solid 0.4 border -1    //  solid后面的数值是`0~1`之间的值,表示颜色的透明度; **使用此办法打印出来的图表是灰色的**, border -1 指明柱子边框是黑色的 

set style fill pattern 4 border -1  //使用这种方法是用斜线填充,绘制的图表比较适合打印。

三维图splot(surface plot)

splot '文件名' u 2:4:5 //以第二列和第四列作为x和y坐标,第五列作为z坐标

show命令

show functions //显示所有使用者定义的函数

show variables //显示所有使用者定义的常数。

在同一张图同时画多个图

set multiplot      //设置为多图模式
set origin 0.0,0.5    //设置第一个图的原点位置

set size 0.5,0.5     //设置第一个图的大小
plot 'a.dat'        

set origin 0.5,0.5     //设置第二个图的原点的位置

`set size 0.5,0.5`     //设置第二个图的大小

plot `b.dat`

set origin 0,0      //设置第三个图的原点的位置

set size 0.5,0.5     //设置第三个图的大小

plot 'a3.dat'    

set origin 0.5,0.0 

set size 0.5,0.5     

plot 'a4.dat'
unset multiplot

或者

set multiplot layout 2,2
plot sin(x)
plot x**3
plot exp(x)
plot abs(x)
unset multiplot

如果后一个图的某个量和前一个相同,那么后一个图的这个量的设置可以省略,例如第一个图对图形大小的设置也会对后来第二,三,四个图的大小设置起作用,如果要取消,可以使用unset命令。

set terminal pngcairo size 600,900
set output 'stacking.png'

set lmargin at screen 0.15
set rmargin at screen 0.95

TOP=0.98
DY=0.29

set multiplot

set offset 0,0,graph 0.05, graph 0.05

set xlabel 'time'
set ylabel 'ylable 1' offset 1
set tmargin at screen TOP-2*DY
set bmargin at screen TOP-3*DY       //图形的高度就是DY
set yticks -1000,500,1000
plot 1150*cos(x) title ‘First’

set xtics format ''
unset xlabel     //上面的xlabel会对之后的图同样起作用,所以使用unset取消
set ylabel 'ylabel 2' offset 0
set tmargin at screen TOP-DY
set bmargin at screen TOP-2*DY
set ytics -100,50,100
plot 101*sin(x) title 'Second'

set ylabel 'ylabel 3' offset -1
set tmargin at screen TOP
set bmargin at screen TOP-DY
set ytics -8,4,8
plot 10*sin(2*x) title 'Third'

unset multiplot; set output

接下来对上述图做改进,让每个图之间可以预留出一些空隙

#! /bin/sh
gnuplot<<!
set terminal pngcairo size 600, 900
set output 'stacking.png'

set lmargin at screen 0.15
set rmargin at screen 0.95

TOP=0.98
DY = 0.21
seam=0.02

set multiplot
set offset 0,0,graph 0.05, graph 0.05
set xlabel 'time'
set ylabel 'ylabel 0' offset 1
set tmargin at screen TOP-3*DY-3*seam
set bmargin at screen TOP-4*DY-3*seam
set ytics -4 2 4
plot 8*cos(x) title 'Zero'

set xtics format ''
unset xlabel
set ylabel 'ylabel 1' offset 1
set tmargin at screen TOP-2*DY-2*seam
set bmargin at screen TOP-3*DY-2*seam
set ytics -1000,500,1000
plot 1150*cos(x) title 'First'


set ylabel 'ylabel 2' offset 1
set tmargin at screen TOP-DY-1*seam
set bmargin at screen TOP-2*DY-1*seam
set ytics -100,50,100
plot 101*sin(x) title 'Second'

set ylabel 'ylabel 3' offset 1
set tmargin at screen TOP
set bmargin at screen TOP-DY
set ytics -8,4,8
plot 10*sin(2*x) title 'Third'

unset multiplot;
set output
exit
!

接着上下左右各两个图

#! /bin/sh
#set lmargin at screen 0.15
#set rmargin at screen 0.95
gnuplot<<!
set terminal pngcairo size 600, 900
set output 'stacking.png'



TOP=0.98
DY = 0.45
seam=0.02
x_gap=0.02
central_axis=0.55

set multiplot
set offset 0,0,graph 0.05, graph 0.05
set xlabel 'time'
set ylabel 'ylabel 0' offset 1
set lmargin at screen 0.15
set rmargin at screen central_axis-x_gap
set tmargin at screen TOP-1*DY-seam
set bmargin at screen TOP-2*DY-seam
set ytics -4 2 4
plot 8*cos(x) title 'Zero'

set xlabel 'time'
unset ylabel
set lmargin at screen central_axis+x_gap
set rmargin at screen 0.95
set tmargin at screen TOP-1*DY-seam
set bmargin at screen TOP-2*DY-seam
set ytics -1000,500,1000
plot 1150*cos(x) title 'First'

set xtics format ''
unset xlabel
set ylabel 'ylabel 2' offset 1
set lmargin at screen 0.15
set rmargin at screen central_axis-x_gap
set tmargin at screen TOP
set bmargin at screen TOP-DY
set ytics -100,50,100
plot 101*sin(x) title 'Second'

set xtics format ''
unset ylabel
set lmargin at screen central_axis+x_gap
set rmargin at screen 0.95
set tmargin at screen TOP
set bmargin at screen TOP-DY
set ytics -8,4,8
plot 10*sin(2*x) title 'Third'

unset multiplot;
set output
exit
!

如何在同一张图中利用左右两边的y轴分别画图

set xtics nomirror   % 去除上面坐标轴x2的刻度

set ytics nomirror    % 去除右边坐标轴y2的刻度

set x2tics         % 让上面坐标轴x2刻度自动生成

set y2tics          % 让右边坐标轴y2的刻度

plot sin(x),cos(x) axes x1y2     % cos(x)用x1y2坐标,axes x1y2表示用x1y2坐标轴

plot sin(x), cos(x) axes x2y2   //cos(x)用x2y2坐标,axes x2y2 表示用x2y2坐标轴

set x2range[-20:20]    % 设定x2坐标的范围

replot

set xlabel 'x'

set ylabel 'y'

set x2label 't'

set y2label 's'

replot

set title 'The figure'

replot

set x2label 't' textcolor(简写为tc) lt 3   % textcolor lt 3 设置坐标轴名称的颜色  

图形动起来

f(x,t)=sin(x-t)
set term gif animate delay 4
set output "test.gif"
set xrange[-20:20]
set yrange[-2:2]
do for [i=1:96]{plot f(x,i*0.1)}
set samples 200
do for [i=1:96]{plot f(x,i*0.1)}

插入希腊字母和特殊字符

一般只能在pseps中可以使用,且必须指定enhanced选项。 set terminal postscript enhanced 希腊字母可以通过{/Symbol a}输入, 例如set label {/Symbol a}

各种希腊字母与特殊符号的输入方法请见安装包中gnuplot-4.0.0/docs/psdoc目录下的ps_guide.ps文件。

也可以参考这个链接

Gnuplot画等高线

splot '文件名.dat' u 1:2:3 w l % 做三维图

set dgrid3d 100,100 % 设置三维图表面的网格数目

set contour % 设置画等高线

set cntrparam levels incremental -0.2,0.01,0.2 %设置等高线的疏密和范围,数据从-0.2到0.2中间每隔0.01画一条线

unset surface % 去除上面的三维图形

set view 0,0 % 选用合适的角度

画三维图的数据文件必须是分块的,也就是x每变换一个值,y在其变化范围变化一周,这样作为一块, 然后在取一个x值,y在变化一周,作为下一个数据块,块与快之间用一空格分开。

画漂亮的pm3d图

set pm3d     % 设置pm3d模式
set isosamples 50,50    % 设置网格点
splot x**2+y**2       % 画三维图
splot x**2+y**2 w pm3d   % 画成pm3d模式,注意变化

set view 0,0        % 设置视角,(0,0)将投影到底面上去
unset ztics        % 将z轴上的数字给去掉
set isosamples 200,200     % 将网格变细

replot

使用Gnuplot拟合图像

y(x)=a*exp(-b*x)

fit y(x) 'rk4th.dat' via a,b       // 拟合上述猜测的公式得出系数a,b

plot `rk4th.dat` w lp, y(x) lc(line color) rgb 'black'

使用脚本绘制gnuplot

  1. 方法1:使用load命令
set terminal png size 1400,700 font "/usr/share/fonts/kingsoft/simfang.ttf,14"
set output "ab测试结果.png"
set title "ab测试"
set size 1,0.8
set grid y
set xlabel "并发数"
set xrange [0:2000]

set ylabel "响应时间(ms)"
set yrange [0:100]
set ytics nomirror
set y2label "吞吐率"
set y2tics

plot "ab-result.dat" using 1:4 smooth sbezier with linespoint pointtype 2title "吞吐率"\
,"ab-result.dat" using 1:3 smooth sbezier with linespoint pointtype 3 axis x1y2 title "响应时间/y2轴"

set output

将其保存为***.txt(一般为plt后缀的文件)文件,然后在gnuplot绘图命令模式下,使用load ***.txt命令加载。

  1. 方法2: 在shell模式下使用
#!/bin/bash

echo "本脚本基于绘图软件gnuplot,使用前请确保gnuplot正确安装"
echo -e "以centos为例:\n\t yum install -y gnuplot"
echo -e "脚本使用帮助:\n\t sh abdraw.sh -h"

# 默认参数
## 服务器类型
server=
## 图片大小
sizel=1400
sizeh=700
## x轴设置
xmin=50
xmax=1000
xtics=50
## 左侧y轴坐标范围
ymin=15000
ymax=30000
## 数据文件路径
dir=.
file=abresult.dat

function usage(){
    echo -e "命令格式: \n sh abdraw.sh <commands..>"
    echo "   -S --server        目标服务器名,用途title携带,可选"
    echo "   -d --dir           数据文件夹,必传"
    echo "   -f --file          数据文件名,默认adresult.dat,可选"
    exit
}

ARGS=`getopt -a -o S:d:f:h -l server:,dir:,file:,help -- "$@"`
eval set -- "${ARGS}"

while true
do
    case "$1" in
        -S|--server)
          server="$2"
          shift
          ;;
        -d|--dir)
          dir="$2"
          shift
          ;;
        -f|--file)
          file="$2"
          shift
          ;;
        -h|--help)
           usage
           ;;
        --)
          shift
          break
          ;;
    esac
    shift
done

if [ ! -d $dir ]; then
    echo "文件夹$dir不存在"
elif [ ! -f $dir/$file ]; then
    echo "数据文件$dir/$file不存在"
fi

gnuplot -persist <<EOF

set terminal png size $sizel,$sizeh font "/usr/share/fonts/kingsoft/simfang.ttf,14"
set output "$dir/ab测试结果.png"
set title "ab测试 $server"
set size 1,0.8
set grid y
set xlabel "并发数"
set xrange [$xmin:$xmax]
set xtics $xtics

set ylabel "吞吐率"
set yrange [$ymin:$ymax]
set ytics nomirror
set y2label "响应时间/y2"
set y2tics

plot "$dir/$file" using 1:4 smooth sbezier with lines title "吞吐率"\
,"$dir/$file" using 1:3 smooth sbezier with linespoint pointtype 3 axis x1y2 title "响应时间/y2轴"

set output

EOF


Gnuplot模式下运行linux命令

gnuplot提示符下输入! 就可以运行linux命令,例如!vim a,dat

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

latex的结合

如果使用png可能会出现一些问题:

  • 字体与latex字体不一样

  • 放大会失真

set terminal epslatex (size 3.5 2)     //默认的尺寸是5in, 3.5in
set output "disp.tex"
set yzeroaixs lt -1 
set xtics("$-\\pi/a$" -pi, "$0$""$\\pi/a$", pi)

分类:

后端

标签:

后端

作者介绍

E
EdwardWong
V1