首页 > 解决方案 > 如何在gnuplot的一个窗口中合并所有图

问题描述

我知道类似的问题在 SO 中被多次询问和回答。在这里,我有一些独特的东西,包括每个情节的拟合。我在用

f(x) = (a0 + a1/x)
fit f(x) 'test.data' using 1:2 via a0,a1
plot 'test.data' using 1:2 w points pt 1 t  ,  f(x) t sprintf("K_{fit} = a_0 +  a_1/T", a0)

f(x) = (a0 + a1/x)
fit f(x) 'test.data' using 1:3 via a0,a1
plot 'test.data' using 1:3 w points pt 1 t  ,  f(x) t sprintf("K_{fit} = a_0 +  a_1/T", a0)

在这里,我将跳过其他绘图命令以保持查询简短。

f(x) = (a0 + a1/x)
fit f(x) 'test.data' using 1:8 via a0,a1
plot 'test.data' using 1:8 w points pt 1  ,  f(x) t sprintf("K_{fit} = a_0 +  a_1/T", a0)

f(x) = (a0 + a1/x)
fit f(x) 'test.data' using 1:9 via a0,a1
plot 'test.data' using 1:9 w points pt 1 t   ,  f(x) t sprintf("K_{fit} = a_0 +  a_1/T", a0)

使用上面的图,我为每个图得到一个框。

如何在一个窗口中合并所有图?

数据文件有 9 列(第一列将是 x 轴,而其他列是 y 轴)并且为每个图插入绘图命令会使 gnuplot 脚本太长。是否有任何解决方法,这样我就不需要每次都输入 p"plot 并且可以通过某个循环来完成这项工作?

我试图在一个盒子里管理所有地块

plot for [i=1:9] 'test.data' using (i):i notitle with boxplot lt -1, \
f(x) = (a0 + a1/x)
fit f(x) 'test.data'for [i=1:9] using (i):i via a0,a1 
plot 'test.data' for [i=1:9] using (i):i w points pt 1 t ,  f(x) t sprintf("K_{fit} = a_0 +  a_1/T", a0)

但我得到以下错误

fit f(x) 'test.data'for [i=1:9] using (i):i via a0,a1 
                        ^
"test.gnu", line 23: Need via and either parameter list or file

下面是我的 test.data 文件

100.0 0.45564E+02 0.20558E+02   0.53903E+02 0.24899E+02 0.56334E+02 0.26169E+02 0.58482E+02 0.27273E+02
200.0 0.17118E+02 0.81681E+01   0.18147E+02 0.86680E+01 0.18397E+02 0.87831E+01 0.18598E+02 0.88736E+01
300.0 0.10908E+02 0.53456E+01   0.11307E+02 0.55301E+01 0.11398E+02 0.55703E+01 0.11470E+02 0.56013E+01
400.0 0.81160E+01 0.40313E+01   0.83328E+01 0.41288E+01 0.83808E+01 0.41496E+01 0.84181E+01 0.41655E+01
500.0 0.64937E+01 0.32506E+01   0.66311E+01 0.33115E+01 0.66611E+01 0.33243E+01 0.66841E+01 0.33340E+01
600.0 0.54231E+01 0.27282E+01   0.55185E+01 0.27700E+01 0.55390E+01 0.27787E+01 0.55547E+01 0.27853E+01
700.0 0.46602E+01 0.23525E+01   0.47305E+01 0.23830E+01 0.47455E+01 0.23894E+01 0.47569E+01 0.23942E+01
800.0 0.40878E+01 0.20687E+01   0.41419E+01 0.20920E+01 0.41533E+01 0.20968E+01 0.41620E+01 0.21005E+01
900.0 0.36419E+01 0.18465E+01   0.36847E+01 0.18649E+01 0.36937E+01 0.18687E+01 0.37006E+01 0.18716E+01
1000.0 0.32843E+01 0.16677E+01  0.33192E+01 0.16826E+01 0.33264E+01 0.16857E+01 0.33320E+01 0.16880E+01

标签: gnuplotcurve-fitting

解决方案


如果您检查help fit,您将不会发现 gnuplot 可以像在绘图循环中那样适合循环。但是您可以在一个do for循环中放置多个数据列,检查help do. 您可以将拟合参数存储在数组中,以便稍后在plot for循环中绘制它们。我希望你能弄清楚下面的示例代码是如何工作的。

代码:

### fit multiple columns in a loop
reset session

f(x) = a0 + a1/x

# arrays for fit parameters
array arr0[8]
array arr1[8]

# create some random test data
do for [i=1:8] {
    arr0[i] = int(rand(0)*50)+5
    arr1[i] = int(rand(0)*10)+5
}
set print $Data
do for [x=10:50] {
    line = sprintf("%g",x/100.)
    do for [i=1:8] {
        a0 = arr0[i]
        a1 = arr1[i]
        line = line.sprintf(" %.3f",f(x/100.)+10*i)
    }
    print line
}
set print

# fit columns in a loop and put fit values into array
do for [i=1:8] {
    fit f(x) $Data u 1:i+1 via a0,a1
    arr0[i] = a0
    arr1[i] = a1
} 

set key Left
plot for [i=1:8] $Data u 1:i+1 ti sprintf("%d: a0=%.1f, a1=%.1f",i,arr0[i],arr1[i]), \
     for [i=1:8] tmp=(a0=arr0[i],a1=arr1[i]) f(x) w l lc rgb "red" not
     
### end of code

结果:

在此处输入图像描述

加法(使用 OP 的数据)

代码:

### fit multiple columns in a loop
reset session

f(x) = a0 + a1/x

# arrays for fit parameters
array arr0[8]
array arr1[8]

$Data <<EOD
100.0 0.45564E+02 0.20558E+02   0.53903E+02 0.24899E+02 0.56334E+02 0.26169E+02 0.58482E+02 0.27273E+02
200.0 0.17118E+02 0.81681E+01   0.18147E+02 0.86680E+01 0.18397E+02 0.87831E+01 0.18598E+02 0.88736E+01
300.0 0.10908E+02 0.53456E+01   0.11307E+02 0.55301E+01 0.11398E+02 0.55703E+01 0.11470E+02 0.56013E+01
400.0 0.81160E+01 0.40313E+01   0.83328E+01 0.41288E+01 0.83808E+01 0.41496E+01 0.84181E+01 0.41655E+01
500.0 0.64937E+01 0.32506E+01   0.66311E+01 0.33115E+01 0.66611E+01 0.33243E+01 0.66841E+01 0.33340E+01
600.0 0.54231E+01 0.27282E+01   0.55185E+01 0.27700E+01 0.55390E+01 0.27787E+01 0.55547E+01 0.27853E+01
700.0 0.46602E+01 0.23525E+01   0.47305E+01 0.23830E+01 0.47455E+01 0.23894E+01 0.47569E+01 0.23942E+01
800.0 0.40878E+01 0.20687E+01   0.41419E+01 0.20920E+01 0.41533E+01 0.20968E+01 0.41620E+01 0.21005E+01
900.0 0.36419E+01 0.18465E+01   0.36847E+01 0.18649E+01 0.36937E+01 0.18687E+01 0.37006E+01 0.18716E+01
1000.0 0.32843E+01 0.16677E+01  0.33192E+01 0.16826E+01 0.33264E+01 0.16857E+01 0.33320E+01 0.16880E+01
EOD

# fit columns in a loop and put fit values into array
set fit nolog
do for [i=1:8] {
    fit f(x) $Data u 1:i+1 via a0,a1
    arr0[i] = a0
    arr1[i] = a1
} 

set key Left
plot for [i=1:8] $Data u 1:i+1 ti sprintf("%d: a0=%.1f, a1=%.1f",i,arr0[i],arr1[i]), \
     for [i=1:8] tmp=(a0=arr0[i],a1=arr1[i]) f(x) w l lc rgb "red" not
     
### end of code

结果:

在此处输入图像描述

补充:(在您的评论之后)

您还可以在循环中绘制数据。您可以简单地为线型和虚线型定义函数。Dashtypedt 1是实线,dt 2是与 基本相同的虚线dt "-"test在 gnuplot 控制台中输入,您将看到不同的线条样式。

也许也是对这个词的解释tmp=(a0=arr0[i],a1=arr1[i])。您可以在绘图命令中添加一个定义(参见help plot),但由于我们需要两个定义a0=arr0[i],并且a1=arr1[i]我们使用串行评估(参见help operators binary)并将其分配给一个虚拟变量tmp

您的函数和绘图命令将是:

myLineType(i) = (i-1)/2+1    # Attention: /2 in gnuplot is integer division if `i` is integer!
myDashType(i) = (i-1)%2+1    # % is modulo

plot for [i=1:8] $Data u 1:i+1 w l lw 2 lt myLineType(i) dt myDashType(i) not, \
     for [i=1:8] tmp=(a0=arr0[i],a1=arr1[i]) f(x) w p lt myLineType(i) not

推荐阅读