如何在gnuplot中使用第三个变量作为线性拟合的拟合范围
how to use 3rd variable as fitting range in linear fit in gnuplot
我对 gnuplot 中的数据拟合有一些疑问。假设我的数据格式如下数据示例:test.txt
# x y y_unc
1 0.20124531 2415.58 8.25706
2 0.20516169 2416.44 8.20651
3 0.21008456 2418.48 8.12084
4 0.21531272 2420.98 8.14102
5 0.22070909 2423.81 8.08436
6 0.2259568 2426.22 8.11353
7 0.23033106 2426.90 8.10172
8 0.23536205 2428.67 8.12772
9 0.24108887 2431.43 8.0769
10 0.24623346 2433.40 8.10201
11 0.252087 2436.33 8.19167
12 0.25853813 2439.53 8.14111
13 0.2634114 2441.27 8.14649
14 0.26842701 2442.58 8.19902
15 0.27422249 2444.09 8.25536
16 0.2799958 2447.22 8.32832
17 0.28573883 2449.42 8.37259
18 0.29226887 2452.35 8.34731
19 0.29696763 2453.71 8.32749
20 0.3020314 2454.80 8.40804
21 0.30853319 2457.60 8.3655
22 0.31335223 2459.26 8.41802
23 0.31937134 2461.96 8.4152
24 0.32383776 2461.80 8.45517
25 0.32963562 2464.02 8.49144
26 0.33469725 2465.15 8.37373
27 0.34041607 2467.62 8.30546
28 0.34591591 2469.44 8.30957
29 0.35146141 2471.29 8.37891
30 0.35608864 2471.50 8.30454
31 0.36138475 2472.98 8.31596
32 0.36773384 2476.24 8.43088
33 0.37238193 2476.59 8.34855
34 0.37814891 2478.86 8.26447
35 0.38311863 2479.65 8.28821
36 0.38847184 2481.35 8.25968
37 0.39456666 2484.14 8.21979
38 0.40007389 2486.06 8.16865
39 0.40610838 2488.30 8.25412
40 0.41157734 2490.10 8.29775
41 0.41630316 2491.59 8.31229
42 0.42112446 2492.40 8.26294
43 0.42697787 2494.75 8.32757
44 0.43137014 2495.07 8.36824
45 0.43700123 2496.25 8.46014
46 0.4422034 2497.68 8.45171
47 0.44765294 2500.41 8.42395
48 0.45317519 2502.29 8.48215
49 0.45835781 2503.81 8.50099
50 0.46392608 2505.78 8.61147
51 0.46943402 2508.04 8.60481
52 0.47533679 2510.15 8.58076
53 0.47967601 2510.77 8.6058
54 0.48523116 2513.11 8.63744
55 0.49090195 2515.74 8.8106
56 0.49617493 2517.32 8.8445
57 0.50119078 2518.77 8.87158
58 0.5066849 2520.57 8.93972
59 0.51132584 2522.25 8.91477
60 0.51644492 2524.03 8.89287
61 0.52197838 2526.33 9.00516
62 0.52705693 2528.27 8.92575
63 0.53193879 2529.73 8.95115
64 0.53704453 2531.44 8.99157
65 0.54210413 2532.46 9.03761
66 0.54626262 2533.34 9.00458
67 0.55056 2534.07 8.99342
68 0.55507934 2535.02 9.04953
69 0.55982471 2536.35 8.97597
70 0.56411815 2536.96 9.01189
71 0.56895626 2537.75 9.01932
72 0.57330275 2539.28 8.99917
73 0.57795715 2540.63 8.98475
74 0.58263767 2541.96 9.01778
75 0.58747137 2543.59 9.08297
76 0.59117234 2543.47 9.07999
77 0.59538865 2543.54 9.11839
78 0.59938073 2544.33 9.1549
79 0.60377049 2545.28 9.18278
80 0.60801435 2545.99 9.17474
81 0.61249495 2547.23 9.21996
82 0.61721373 2548.98 9.13147
83 0.62135947 2549.96 9.15198
84 0.6255244 2550.66 9.09919
85 0.629843 2551.9 9.15456
86 0.63427138 2553.34 9.21929
87 0.6376698 2552.96 9.19235
88 0.6422739 2554.31 9.24774
89 0.6468153 2555.74 9.1766
90 0.65102458 2556.53 9.22202
91 0.65579379 2558.13 9.16892
92 0.66031909 2559.52 9.20696
93 0.66545904 2561.28 9.29657
94 0.66935432 2561.9 9.23281
95 0.67299354 2562.15 9.28052
96 0.67770863 2564.20 9.37245
97 0.68189645 2565.98 9.48318
98 0.68605471 2566.81 9.56233
99 0.69018805 2567.83 9.59128
100 0.69424725 2568.67 9.63816
我尝试将第 2 列中的数据与第 3 列中的数据进行拟合。到目前为止,我可以使用以下代码进行拟合
# Fitting data from file
reset session
set terminal qt size 800,480
set key left
FILE = 'test.txt'
# fit function
f(x) = a*x+b
fit [0.25:0.58] f(x) FILE u 2:3 via a,b
chi2=(FIT_STDFIT*FIT_STDFIT)
# setting label
set label 1 'Fit Parameters' left at graph 0.7, graph 0.95 font "arial,15"
set label 2 sprintf("y= %.2fx + %.2f", a,b)left at graph 0.7, graph 0.90 font "arial,10"
set label 3 sprintf("a = %.2f %.2s %.2f",a,'±',a_err) left at graph 0.7, graph 0.86 font "arial,10"
set label 4 sprintf("b = %.2f %.2s %.2f",b,'±',b_err) left at graph 0.7, graph 0.82 font "arial,10"
set label 5 sprintf("ndf = %.2f ", FIT_NDF) left at graph 0.7, graph 0.78 font "arial,10"
set label 6 sprintf("{/Symbol c}^2/ndf = %.2f ", chi2) left at graph 0.7, graph 0.74 font "arial,10"
# setting label box
set arrow 1 nohead at 0.51, 2755 to 0.75, 2755
set obj 10 rect at 0.63, 2710 size 0.25, 160
set obj 10 fillstyle empty border -1 front
# setting range
set xrange [0:0.8]
set yrange [2200:2800]
set ytics nomirror
set y2range [-50:300]
set y2tics
set x2zeroaxis lt -1
set xlabel 'x-axis'
set ylabel 'y-axis'
set y2label 'residual'
# plotting
plot FILE u 2:3:4 w yerr pt 7 lc rgb 'black' ti 'data',\
[0:0.58] f(x) w l lw 2 lc rgb 'red' ti 'fit',\
[0.25:0.58] FILE u 2:(f()-) pt 1 axes x1y2 ti 'residual'
# end code
并且使用测试数据我可以得到这个结果:
我的主要问题是:是否可以使用第三个变量,例如第 1 列中的行号作为拟合范围,而不是使用 x 值?例如,使用 [1:5] 来拟合前 5 个数据,而不是使用 [0.20:0.22].
关于我上面的代码的其他问题,我将残差与拟合一起绘制,但我想将残差图限制在拟合数据内。使用上面的代码,绘制了整个数据的残差,当 运行 此代码时,我收到警告:“忽略非采样数据中的样本范围”。有什么办法可以解决这个问题吗?
最后一个,有没有更简单的方法来在图中打印拟合参数而不是使用标签?
据我了解,您有几个问题:
- 将一列与另一列相比较,同时通过第三列限制范围
- 用拟合结果简化标签
- 避免警告:“忽略非样本数据中的样本范围”
ad 1:写一个过滤函数,例如myRange(colD,colR,min,max)
其中 returns NaN
超出了所需的范围。 colD
是数据列,colR
是范围列,min,max
是范围的界限。
广告 2: 您可以在标签中使用换行符 \n
并使用增强文本。检查 help enhanced
。您可以使用 set style textbox
制作一个框,可能不适用于所有终端,请选中 help textbox
。仍然有点混乱,但肯定比绘制许多手动放置的标签、箭头和框要简单。
广告 3: 再次通过您的过滤功能限制您的剧情(参见广告 1)
所以,下面的代码:
- 绘制整个范围内的数据
- 在有限范围内拟合数据,受第 3 列限制
- 绘制给定范围内的拟合,此处:
[0:0.58]
- 在有限范围内绘制残差,受第 3 列限制
- 放置带有结果的标签
也许有更简单的解决方案,我目前还不知道。
代码:
### limit fit and plotting range via 3rd column
reset session
$Data <<EOD
# x y y_unc
1 0.20124531 2415.58 8.25706
2 0.20516169 2416.44 8.20651
3 0.21008456 2418.48 8.12084
4 0.21531272 2420.98 8.14102
5 0.22070909 2423.81 8.08436
6 0.2259568 2426.22 8.11353
7 0.23033106 2426.90 8.10172
8 0.23536205 2428.67 8.12772
9 0.24108887 2431.43 8.0769
10 0.24623346 2433.40 8.10201
20 0.4 2500 8.0 # just added to show the larger range
30 0.5 2560 8.0
EOD
# filter function
myRange(colD,colR,min,max) = column(colR)>=min && column(colR)<=max ? column(colD) : NaN
# fit function
f(x) = a*x+b
fit f(x) $Data u (myRange(2,1,1,5)):3 via a,b
chi2=(FIT_STDFIT*FIT_STDFIT)
# setting label
set label 1 at graph 0.7, graph 0.95 boxed \
sprintf("%s\n%s\n%s\n%s\n%s\n%s", \
"{/'Arial':Bold=14 Fit Parameters}", \
sprintf("y= %.2fx + %.2f", a,b), \
sprintf("a = %.2f %.2s %.2f",a,'±',a_err), \
sprintf("b = %.2f %.2s %.2f",b,'±',b_err), \
sprintf("ndf = %.2f ", FIT_NDF), \
sprintf("{/Symbol c}^2/ndf = %.2f ", chi2))
set style textbox border
set key left
# setting range
set xlabel 'x-axis'
set xrange [0:0.8]
set ylabel 'y-axis'
set yrange [2200:2800]
set ytics nomirror
set y2label 'residual'
set y2range [-50:300]
set y2tics
set x2zeroaxis lt -1
plot $Data u 2:3:4 w yerr pt 7 lc rgb 'black' ti 'data',\
[0:0.58] f(x) w l lw 2 lc rgb 'red' ti 'fit',\
$Data u (myRange(2,1,1,5)):(f()-) pt 1 axes x1y2 ti 'residual'
### end of code
结果:
我对 gnuplot 中的数据拟合有一些疑问。假设我的数据格式如下数据示例:test.txt
# x y y_unc
1 0.20124531 2415.58 8.25706
2 0.20516169 2416.44 8.20651
3 0.21008456 2418.48 8.12084
4 0.21531272 2420.98 8.14102
5 0.22070909 2423.81 8.08436
6 0.2259568 2426.22 8.11353
7 0.23033106 2426.90 8.10172
8 0.23536205 2428.67 8.12772
9 0.24108887 2431.43 8.0769
10 0.24623346 2433.40 8.10201
11 0.252087 2436.33 8.19167
12 0.25853813 2439.53 8.14111
13 0.2634114 2441.27 8.14649
14 0.26842701 2442.58 8.19902
15 0.27422249 2444.09 8.25536
16 0.2799958 2447.22 8.32832
17 0.28573883 2449.42 8.37259
18 0.29226887 2452.35 8.34731
19 0.29696763 2453.71 8.32749
20 0.3020314 2454.80 8.40804
21 0.30853319 2457.60 8.3655
22 0.31335223 2459.26 8.41802
23 0.31937134 2461.96 8.4152
24 0.32383776 2461.80 8.45517
25 0.32963562 2464.02 8.49144
26 0.33469725 2465.15 8.37373
27 0.34041607 2467.62 8.30546
28 0.34591591 2469.44 8.30957
29 0.35146141 2471.29 8.37891
30 0.35608864 2471.50 8.30454
31 0.36138475 2472.98 8.31596
32 0.36773384 2476.24 8.43088
33 0.37238193 2476.59 8.34855
34 0.37814891 2478.86 8.26447
35 0.38311863 2479.65 8.28821
36 0.38847184 2481.35 8.25968
37 0.39456666 2484.14 8.21979
38 0.40007389 2486.06 8.16865
39 0.40610838 2488.30 8.25412
40 0.41157734 2490.10 8.29775
41 0.41630316 2491.59 8.31229
42 0.42112446 2492.40 8.26294
43 0.42697787 2494.75 8.32757
44 0.43137014 2495.07 8.36824
45 0.43700123 2496.25 8.46014
46 0.4422034 2497.68 8.45171
47 0.44765294 2500.41 8.42395
48 0.45317519 2502.29 8.48215
49 0.45835781 2503.81 8.50099
50 0.46392608 2505.78 8.61147
51 0.46943402 2508.04 8.60481
52 0.47533679 2510.15 8.58076
53 0.47967601 2510.77 8.6058
54 0.48523116 2513.11 8.63744
55 0.49090195 2515.74 8.8106
56 0.49617493 2517.32 8.8445
57 0.50119078 2518.77 8.87158
58 0.5066849 2520.57 8.93972
59 0.51132584 2522.25 8.91477
60 0.51644492 2524.03 8.89287
61 0.52197838 2526.33 9.00516
62 0.52705693 2528.27 8.92575
63 0.53193879 2529.73 8.95115
64 0.53704453 2531.44 8.99157
65 0.54210413 2532.46 9.03761
66 0.54626262 2533.34 9.00458
67 0.55056 2534.07 8.99342
68 0.55507934 2535.02 9.04953
69 0.55982471 2536.35 8.97597
70 0.56411815 2536.96 9.01189
71 0.56895626 2537.75 9.01932
72 0.57330275 2539.28 8.99917
73 0.57795715 2540.63 8.98475
74 0.58263767 2541.96 9.01778
75 0.58747137 2543.59 9.08297
76 0.59117234 2543.47 9.07999
77 0.59538865 2543.54 9.11839
78 0.59938073 2544.33 9.1549
79 0.60377049 2545.28 9.18278
80 0.60801435 2545.99 9.17474
81 0.61249495 2547.23 9.21996
82 0.61721373 2548.98 9.13147
83 0.62135947 2549.96 9.15198
84 0.6255244 2550.66 9.09919
85 0.629843 2551.9 9.15456
86 0.63427138 2553.34 9.21929
87 0.6376698 2552.96 9.19235
88 0.6422739 2554.31 9.24774
89 0.6468153 2555.74 9.1766
90 0.65102458 2556.53 9.22202
91 0.65579379 2558.13 9.16892
92 0.66031909 2559.52 9.20696
93 0.66545904 2561.28 9.29657
94 0.66935432 2561.9 9.23281
95 0.67299354 2562.15 9.28052
96 0.67770863 2564.20 9.37245
97 0.68189645 2565.98 9.48318
98 0.68605471 2566.81 9.56233
99 0.69018805 2567.83 9.59128
100 0.69424725 2568.67 9.63816
我尝试将第 2 列中的数据与第 3 列中的数据进行拟合。到目前为止,我可以使用以下代码进行拟合
# Fitting data from file
reset session
set terminal qt size 800,480
set key left
FILE = 'test.txt'
# fit function
f(x) = a*x+b
fit [0.25:0.58] f(x) FILE u 2:3 via a,b
chi2=(FIT_STDFIT*FIT_STDFIT)
# setting label
set label 1 'Fit Parameters' left at graph 0.7, graph 0.95 font "arial,15"
set label 2 sprintf("y= %.2fx + %.2f", a,b)left at graph 0.7, graph 0.90 font "arial,10"
set label 3 sprintf("a = %.2f %.2s %.2f",a,'±',a_err) left at graph 0.7, graph 0.86 font "arial,10"
set label 4 sprintf("b = %.2f %.2s %.2f",b,'±',b_err) left at graph 0.7, graph 0.82 font "arial,10"
set label 5 sprintf("ndf = %.2f ", FIT_NDF) left at graph 0.7, graph 0.78 font "arial,10"
set label 6 sprintf("{/Symbol c}^2/ndf = %.2f ", chi2) left at graph 0.7, graph 0.74 font "arial,10"
# setting label box
set arrow 1 nohead at 0.51, 2755 to 0.75, 2755
set obj 10 rect at 0.63, 2710 size 0.25, 160
set obj 10 fillstyle empty border -1 front
# setting range
set xrange [0:0.8]
set yrange [2200:2800]
set ytics nomirror
set y2range [-50:300]
set y2tics
set x2zeroaxis lt -1
set xlabel 'x-axis'
set ylabel 'y-axis'
set y2label 'residual'
# plotting
plot FILE u 2:3:4 w yerr pt 7 lc rgb 'black' ti 'data',\
[0:0.58] f(x) w l lw 2 lc rgb 'red' ti 'fit',\
[0.25:0.58] FILE u 2:(f()-) pt 1 axes x1y2 ti 'residual'
# end code
并且使用测试数据我可以得到这个结果:
我的主要问题是:是否可以使用第三个变量,例如第 1 列中的行号作为拟合范围,而不是使用 x 值?例如,使用 [1:5] 来拟合前 5 个数据,而不是使用 [0.20:0.22].
关于我上面的代码的其他问题,我将残差与拟合一起绘制,但我想将残差图限制在拟合数据内。使用上面的代码,绘制了整个数据的残差,当 运行 此代码时,我收到警告:“忽略非采样数据中的样本范围”。有什么办法可以解决这个问题吗?
最后一个,有没有更简单的方法来在图中打印拟合参数而不是使用标签?
据我了解,您有几个问题:
- 将一列与另一列相比较,同时通过第三列限制范围
- 用拟合结果简化标签
- 避免警告:“忽略非样本数据中的样本范围”
ad 1:写一个过滤函数,例如myRange(colD,colR,min,max)
其中 returns NaN
超出了所需的范围。 colD
是数据列,colR
是范围列,min,max
是范围的界限。
广告 2: 您可以在标签中使用换行符 \n
并使用增强文本。检查 help enhanced
。您可以使用 set style textbox
制作一个框,可能不适用于所有终端,请选中 help textbox
。仍然有点混乱,但肯定比绘制许多手动放置的标签、箭头和框要简单。
广告 3: 再次通过您的过滤功能限制您的剧情(参见广告 1)
所以,下面的代码:
- 绘制整个范围内的数据
- 在有限范围内拟合数据,受第 3 列限制
- 绘制给定范围内的拟合,此处:
[0:0.58]
- 在有限范围内绘制残差,受第 3 列限制
- 放置带有结果的标签
也许有更简单的解决方案,我目前还不知道。
代码:
### limit fit and plotting range via 3rd column
reset session
$Data <<EOD
# x y y_unc
1 0.20124531 2415.58 8.25706
2 0.20516169 2416.44 8.20651
3 0.21008456 2418.48 8.12084
4 0.21531272 2420.98 8.14102
5 0.22070909 2423.81 8.08436
6 0.2259568 2426.22 8.11353
7 0.23033106 2426.90 8.10172
8 0.23536205 2428.67 8.12772
9 0.24108887 2431.43 8.0769
10 0.24623346 2433.40 8.10201
20 0.4 2500 8.0 # just added to show the larger range
30 0.5 2560 8.0
EOD
# filter function
myRange(colD,colR,min,max) = column(colR)>=min && column(colR)<=max ? column(colD) : NaN
# fit function
f(x) = a*x+b
fit f(x) $Data u (myRange(2,1,1,5)):3 via a,b
chi2=(FIT_STDFIT*FIT_STDFIT)
# setting label
set label 1 at graph 0.7, graph 0.95 boxed \
sprintf("%s\n%s\n%s\n%s\n%s\n%s", \
"{/'Arial':Bold=14 Fit Parameters}", \
sprintf("y= %.2fx + %.2f", a,b), \
sprintf("a = %.2f %.2s %.2f",a,'±',a_err), \
sprintf("b = %.2f %.2s %.2f",b,'±',b_err), \
sprintf("ndf = %.2f ", FIT_NDF), \
sprintf("{/Symbol c}^2/ndf = %.2f ", chi2))
set style textbox border
set key left
# setting range
set xlabel 'x-axis'
set xrange [0:0.8]
set ylabel 'y-axis'
set yrange [2200:2800]
set ytics nomirror
set y2label 'residual'
set y2range [-50:300]
set y2tics
set x2zeroaxis lt -1
plot $Data u 2:3:4 w yerr pt 7 lc rgb 'black' ti 'data',\
[0:0.58] f(x) w l lw 2 lc rgb 'red' ti 'fit',\
$Data u (myRange(2,1,1,5)):(f()-) pt 1 axes x1y2 ti 'residual'
### end of code
结果: