如何在 gnuplot 中设置统计功能的范围?
How to set the range of stats function in gnuplot?
我有如下所示的时间序列数据,我想绘制所有数据,即特定范围的平均值,例如3、6 或 9 个月。
Time T D T/D
8/1/2021 1785.28 23.99 74.42
7/1/2021 1807.84 25.68 70.40
6/1/2021 1834.57 27 67.95
5/1/2021 1850.26 27.5 67.28
4/1/2021 1760.04 25.69 68.51
3/1/2021 1718.23 25.65 66.99
2/1/2021 1808.17 27.29 66.26
1/1/2021 1866.98 25.88 72.14
12/1/2020 1858.42 24.97 74.43
11/1/2020 1866.3 24.08 77.50
10/1/2020 1900.27 24.23 78.43
9/1/2020 1921.92 25.74 74.67
8/1/2020 1968.63 27 72.91
我正在使用 gnuplot 5.2,我尝试使用以下代码进行绘图,但似乎统计数据没有像我预期的那样工作。
# plot data vs date
reset session
FILE = "data_01.dat"
set timefmt "%m/%d/%Y"
stats ["8/1/2020":"1/1/2021"] FILE u 4 name "A"
stats ["8/1/2020":"8/1/2021"] FILE u 4 name "B"
set label 1 sprintf("6 months average= %.2f",A_mean) at graph 0.02, graph 0.95
set label 2 sprintf("12 months average= %.2f",B_mean) at graph 0.02, graph 0.90
set xdata time
set format x "%m/%y"
set xrange ["8/1/2020":"8/1/2021"]
plot FILE u 1:4 skip 1 w lp lc rgb 'blue' t 'data' ,\
A_mean lc rgb 'black' t '6 months avg',\
B_mean lc rgb 'red' t '12 months avg'
# end of code
我得到的输出是这样的:
data_plot
我想我在设置统计限制时犯了一个错误,这使得统计计算列中整个数据的平均值,而不是在特定范围内计算它。但我找不到如何修复它。起初我尝试使用这个
stats ["8/1/2020":"1/1/2021"] FILE u (timecolumn(1)):4 name "A"
但它没有给我任何输出并以:“未定义的变量:A_mean”结尾。
如何在 gnuplot 中正确设置统计功能的范围?
似乎在stats
内部使用时间数据在gnuplot中并没有实现,至少在5.5版本中是这样。我找到了一个基于 gnuplot: xdata time & calculations 的(丑陋的)解决方法,它将输入时间和范围定义从 1.1.1970 转换为秒,比较输入值是否大于下限和小于上限;如果是,returns 实际的 y 值,如果不是,returns NaN,然后被 stats
.
忽略
reset session
fmt="%m/%d/%Y" #shortcut for the format string
FILE = "data_01.dat"
stats FILE u 1:(strptime(fmt,stringcolumn(1)) >= strptime(fmt,"8/1/2020") && strptime(fmt,stringcolumn(1)) <= strptime(fmt,"1/1/2021") ? : NaN) name "A"
函数说明:strptime
将时间字符串(第二个参数),根据第一个参数格式化,转换为UNIX时间。因此,从文件中读取的 x 值需要作为字符串处理。 </code> 会提供数字,而不是字符串,因此必须使用 <code>stringcolumn
代替。通过这种方式,您可以获得 y 列的平均值,它存储为 A_mean_y
(注意 '_y'!)。
但也许有人有比我更优雅的解决方案……
基本上,Eldrad 已经提到了所有要点...当我还在编码时...
stats
不适用于时间数据,即 set xdata time
。
此外,如果您想限制第一个日期列,您还必须使用 stats
中的第 1 列。
检查将给出合理结果的修改后的代码。
编辑:
除了多次使用 strptime(myTimeFmt,"8/1/2020")
,您还可以定义一个函数 myTime(s) = strptime(myTimeFmt,s)
,它可以稍微缩短所有内容并且不会让它看起来那么“可怕”。
代码:
# plot data vs date and using stats
reset session
$Data <<EOD
Time T D T/D
8/1/2021 1785.28 23.99 74.42
7/1/2021 1807.84 25.68 70.40
6/1/2021 1834.57 27 67.95
5/1/2021 1850.26 27.5 67.28
4/1/2021 1760.04 25.69 68.51
3/1/2021 1718.23 25.65 66.99
2/1/2021 1808.17 27.29 66.26
1/1/2021 1866.98 25.88 72.14
12/1/2020 1858.42 24.97 74.43
11/1/2020 1866.3 24.08 77.50
10/1/2020 1900.27 24.23 78.43
9/1/2020 1921.92 25.74 74.67
8/1/2020 1968.63 27 72.91
EOD
myTimeFmt = "%m/%d/%Y"
set timefmt myTimeFmt
myTime(s) = strptime(myTimeFmt,s)
stats [myTime("8/1/2020"):myTime("1/1/2021")] $Data u (timecolumn(1)):4 name "A" nooutput
stats [myTime("8/1/2020"):myTime("8/1/2021")] $Data u (timecolumn(1)):4 name "B" nooutput
set label 1 sprintf("6 months average= %.2f",A_mean_y) at graph 0.02, graph 0.95
set label 2 sprintf("12 months average= %.2f",B_mean_y) at graph 0.02, graph 0.90
set format x "%m/%y" time
set xrange [myTime("8/1/2020"):myTime("8/1/2021")]
plot $Data u (timecolumn(1)):4 skip 1 w lp lc rgb 'blue' t 'data' ,\
A_mean_y lc rgb 'black' t '6 months avg',\
B_mean_y lc rgb 'red' t '12 months avg'
### end of code
结果:
我有如下所示的时间序列数据,我想绘制所有数据,即特定范围的平均值,例如3、6 或 9 个月。
Time T D T/D
8/1/2021 1785.28 23.99 74.42
7/1/2021 1807.84 25.68 70.40
6/1/2021 1834.57 27 67.95
5/1/2021 1850.26 27.5 67.28
4/1/2021 1760.04 25.69 68.51
3/1/2021 1718.23 25.65 66.99
2/1/2021 1808.17 27.29 66.26
1/1/2021 1866.98 25.88 72.14
12/1/2020 1858.42 24.97 74.43
11/1/2020 1866.3 24.08 77.50
10/1/2020 1900.27 24.23 78.43
9/1/2020 1921.92 25.74 74.67
8/1/2020 1968.63 27 72.91
我正在使用 gnuplot 5.2,我尝试使用以下代码进行绘图,但似乎统计数据没有像我预期的那样工作。
# plot data vs date
reset session
FILE = "data_01.dat"
set timefmt "%m/%d/%Y"
stats ["8/1/2020":"1/1/2021"] FILE u 4 name "A"
stats ["8/1/2020":"8/1/2021"] FILE u 4 name "B"
set label 1 sprintf("6 months average= %.2f",A_mean) at graph 0.02, graph 0.95
set label 2 sprintf("12 months average= %.2f",B_mean) at graph 0.02, graph 0.90
set xdata time
set format x "%m/%y"
set xrange ["8/1/2020":"8/1/2021"]
plot FILE u 1:4 skip 1 w lp lc rgb 'blue' t 'data' ,\
A_mean lc rgb 'black' t '6 months avg',\
B_mean lc rgb 'red' t '12 months avg'
# end of code
我得到的输出是这样的: data_plot
我想我在设置统计限制时犯了一个错误,这使得统计计算列中整个数据的平均值,而不是在特定范围内计算它。但我找不到如何修复它。起初我尝试使用这个
stats ["8/1/2020":"1/1/2021"] FILE u (timecolumn(1)):4 name "A"
但它没有给我任何输出并以:“未定义的变量:A_mean”结尾。 如何在 gnuplot 中正确设置统计功能的范围?
似乎在stats
内部使用时间数据在gnuplot中并没有实现,至少在5.5版本中是这样。我找到了一个基于 gnuplot: xdata time & calculations 的(丑陋的)解决方法,它将输入时间和范围定义从 1.1.1970 转换为秒,比较输入值是否大于下限和小于上限;如果是,returns 实际的 y 值,如果不是,returns NaN,然后被 stats
.
reset session
fmt="%m/%d/%Y" #shortcut for the format string
FILE = "data_01.dat"
stats FILE u 1:(strptime(fmt,stringcolumn(1)) >= strptime(fmt,"8/1/2020") && strptime(fmt,stringcolumn(1)) <= strptime(fmt,"1/1/2021") ? : NaN) name "A"
函数说明:strptime
将时间字符串(第二个参数),根据第一个参数格式化,转换为UNIX时间。因此,从文件中读取的 x 值需要作为字符串处理。 </code> 会提供数字,而不是字符串,因此必须使用 <code>stringcolumn
代替。通过这种方式,您可以获得 y 列的平均值,它存储为 A_mean_y
(注意 '_y'!)。
但也许有人有比我更优雅的解决方案……
基本上,Eldrad 已经提到了所有要点...当我还在编码时...
stats
不适用于时间数据,即 set xdata time
。
此外,如果您想限制第一个日期列,您还必须使用 stats
中的第 1 列。
检查将给出合理结果的修改后的代码。
编辑:
除了多次使用 strptime(myTimeFmt,"8/1/2020")
,您还可以定义一个函数 myTime(s) = strptime(myTimeFmt,s)
,它可以稍微缩短所有内容并且不会让它看起来那么“可怕”。
代码:
# plot data vs date and using stats
reset session
$Data <<EOD
Time T D T/D
8/1/2021 1785.28 23.99 74.42
7/1/2021 1807.84 25.68 70.40
6/1/2021 1834.57 27 67.95
5/1/2021 1850.26 27.5 67.28
4/1/2021 1760.04 25.69 68.51
3/1/2021 1718.23 25.65 66.99
2/1/2021 1808.17 27.29 66.26
1/1/2021 1866.98 25.88 72.14
12/1/2020 1858.42 24.97 74.43
11/1/2020 1866.3 24.08 77.50
10/1/2020 1900.27 24.23 78.43
9/1/2020 1921.92 25.74 74.67
8/1/2020 1968.63 27 72.91
EOD
myTimeFmt = "%m/%d/%Y"
set timefmt myTimeFmt
myTime(s) = strptime(myTimeFmt,s)
stats [myTime("8/1/2020"):myTime("1/1/2021")] $Data u (timecolumn(1)):4 name "A" nooutput
stats [myTime("8/1/2020"):myTime("8/1/2021")] $Data u (timecolumn(1)):4 name "B" nooutput
set label 1 sprintf("6 months average= %.2f",A_mean_y) at graph 0.02, graph 0.95
set label 2 sprintf("12 months average= %.2f",B_mean_y) at graph 0.02, graph 0.90
set format x "%m/%y" time
set xrange [myTime("8/1/2020"):myTime("8/1/2021")]
plot $Data u (timecolumn(1)):4 skip 1 w lp lc rgb 'blue' t 'data' ,\
A_mean_y lc rgb 'black' t '6 months avg',\
B_mean_y lc rgb 'red' t '12 months avg'
### end of code
结果: