gnuplot - 如何在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($2)-$3) pt 1 axes x1y2 ti 'residual'
# end code
并使用测试数据我可以得到这个结果:
我的主要问题是:是否可以使用第三个变量,例如第 1 列中的行号作为拟合范围,而不是使用 x 值?例如,使用 [1:5] 来拟合前 5 个数据,而不是使用 [0.20:0.22]。
关于我上面的代码的附加问题,我将残差与拟合一起绘制,但我想仅在拟合数据内限制残差图。使用上面的代码,为整个数据绘制残差,运行此代码时我收到警告:“忽略非采样数据中的样本范围”。有没有办法解决这个问题?
最后一个,有没有更简单的方法来打印图中的拟合参数而不是使用标签?
解决方案
据我了解,您有几个问题:
- 将一列与另一列相匹配,同时将范围限制为第三列
- 用拟合结果简化标签
- 避免警告:“忽略非样本数据中的样本范围”
ad 1:编写一个过滤函数,例如myRange(colD,colR,min,max)
返回NaN
所需范围之外。colD
是数据列,colR
是范围列,是范围min,max
的限制。
广告 2:您可以在标签中使用换行符\n
并使用增强文本。检查help enhanced
。您可以在 using 周围制作一个框set style textbox
,可能不适用于所有终端,请检查help textbox
. 仍然有点混乱,但肯定比绘制许多手动放置的标签、箭头和框更简单。
广告 3:再次通过您的过滤功能限制您的情节(见广告 1)
所以,下面的代码:
- 绘制整个范围内的数据
- 适合有限范围内的数据,受第三列限制
- 在给定范围内绘制拟合,这里:
[0:0.58]
- 绘制有限范围内的残差,由第三列限制
- 放置带有结果的标签
也许有我目前不知道的更简单的解决方案。
代码:
### 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($2)-$3) pt 1 axes x1y2 ti 'residual'
### end of code
结果:
推荐阅读
- excel - 我需要 Excel VBA 代码以将工作簿另存为非 vba Excel 文件
- c++ - 如何创建 value_type 类型特征?
- excel - 在 VBA 中删除过滤器时,为什么删除的行会重新出现在 Excel 表中?
- python - 用python打印圣诞树
- java - ArrayList 在 Java 中被清除和覆盖
- php - if else WP is_user_logged_in 不显示正确的内容
- selenium - 我如何在多个值上执行鼠标悬停,这些值可以通过样式属性的值来区分,例如“顶部”和“左”
- python - 使用 python ==$0 抓取网页内容在 beautifulsoup 中不可用
- sql - SQL Regexp 对任何单词组合的模式匹配
- c# - 为什么我已经登录时出现登录页面?