我有两个文件
file1.dat
和 file2.dat
,每个文件都包含一个尺寸一致的矩阵(分别为 F1 和 F2)(即它们都是 m x n
矩阵)。我知道如何使用 gnuplot 绘制它们中的任何一个(例如splot "file1.dat" matrix
),但是如何指示 gnuplot 绘制 F1-F2?
不幸的是,(据我所知)无法使用 gnuplot 绘制多个文件中的信息。解决方案是编写一个简单的脚本(用您最喜欢的语言),将两个文件作为输入并将差异写入输出......然后您可以这样做:
splot "<myscript file1.dat file2.dat" matrix ...
我确信,通过足够的哄骗,使用
set table
和 shell 魔法,我可以想出一个 hack 来做你想做的事情(让 gnuplot 输出多个数据文件,发出 shell 命令将数据文件粘贴在一起......),但最终,编写自己的脚本将是一个更干净的解决方案。
这是一个在 gnuplot 中使用 awk 的工作示例。
set terminal postscript enhanced colour
set output 'matrixdiff.eps'
unset key
splot "<awk 'NR==FNR{for(i=1;i<=NF;++i)a[FNR,i]=$i;next}{for(i=1;i<=NF;++i)$i=a[FNR,i]-$i;print}' mat1 mat2" matrix
mat1
和 mat2
是您要绘制的矩阵文件。 awk 脚本来自here。
只是为了好玩和记录,有一个 gnuplot 解决方案,不会变得太复杂,但是,很可能比使用外部工具效率低。 它通过存储在长字符串中的数据进行。对于较小的矩阵,这仍然应该没问题。对于 gnuplot 4.6.0,我看到了大约大约的限制。 38'000 个字符,对应于具有 6 位数字的 64x64 矩阵。对于 gnuplot 5.4,我只测试了 200x200 矩阵没有问题(但需要一些时间来绘制)。
数据:
SO10091196_1.dat
10 11 12 13
24 25 26 27
38 39 40 41
SO10091196_2.dat
10 10 10 10
20 20 20 20
30 30 30 30
脚本:(适用于 gnuplot>=5.0.1,2015 年 6 月)
### plot the difference of two matrices
reset
FILE1 = "SO10091196_1.dat"
FILE2 = "SO10091196_2.dat"
mat2 = ''
stats FILE2 matrix u (cols=$1+1,rows=$2+1,mat2=mat2.sprintf(" %g",$3),0) nooutput
set view map
set xrange [-0.5:cols-0.5]
set yrange [-0.5:rows-0.5]
splot FILE1 matrix u 1:2:($3-real(word(mat2,int($2*cols+1+$1)))) w image
### end of script
对于 gnuplot>=4.4.0(2010 年 3 月)和 <=5.0.0 you need to replace the
stats
行:
cols = rows = 0
set term unknown
plot FILE2 matrix u (cols=$1+1,rows=$2+1,mat2=mat2.sprintf(" %g",$3))
set term wxt # or your default terminal
输出:
补充:
使用数组的 gnuplot>=5.2.0 版本,它比上面的字符串方法快得多,并且没有大小限制(仅测试到 500x500 数组)。
脚本:(适用于 gnuplot>=5.2.0,2017 年 9 月)
### plot the difference of two matrices
reset
FILE1 = "SO10091196_1.dat"
FILE2 = "SO10091196_2.dat"
M = 0 # number of rows, 0 if unknown
N = 0 # number of cols, 0 if unknown
if (!M || !N) {
stats FILE2 u 0 nooutput # get number of rows and cols
M = STATS_records
N = STATS_columns
}
array M2[M*N]
stats FILE2 matrix u (M2[int($2*N+$1+1)] = $3) nooutput # put values into array
set view map
set xrange [-0.5:N-0.5]
set yrange [-0.5:M-0.5]
splot FILE1 matrix u 1:2:($3-M2[int($2*N+$1+1)]) w image
### end of script