Gnuplot 循环遍历数据行以查找索引
Gnuplot loop through data rows to find the index
用 gnuplot 绘制一些 covid19 数据,我试图找到一种方法来在我的数据集中选择原始数据以将其用作起点。
E. G。我有类似的东西:
#date #cases
2010-03-01 11
2010-03-02 13
2020-03-03 17
2020-03-04 20
2020-03-05 29
2020-03-06 38
2020-03-07 50
2020-03-08 63
2020-03-09 82
2020-03-10 105
2020-03-11 140
2020-03-12 180
2020-03-13 240
...
现在我想找到病例数大于 100 的日期,并将此日期用于 adjust/normalise/whatever 我的所有地块。
所以我要以某种方式找到“2020-03-10 105”行并设置两个变量
start_date = '2020-03-10'
start_index = 11
能够做到
stats <datafile> every ::start_index
set xrange [start_date:]
...
等等等等基本上忽略>100个案例日期之前的所有内容。
我想,可以在我的数据文件的原始数据上使用一些基本的 for+if 循环,但我有点受困于他的方法,因为我找不到一个很好的 example/explanation 如何迭代通过数据文件 raws.
P. S. 当然,我可以使用外部工具来完成此操作,但我宁愿不这样做,因为我正在使用相当多的脚本来收集数据,并希望将所有绘图逻辑保留在我的 gnuplot jinja2 中模板不会使整个内容过于复杂。
我不是 gnuplot 专家,所以这可能不是最好的方法。您可以遍历数据文件两次,一次 "plotting" 将其放入一个虚拟数组,但在每一行调用一个函数 f(y,row)
。该函数获取数据点 (y) 和行号,并设置一个变量 (start) 以在数据点超过 100 时记住该行:
set xdata time
set timefmt "%Y-%m-%d"
start=0
f(y,row) = (y>=100 && start==0?(start=row,y):y)
set table $Data
plot "data" using 1:(f(,[=10=]))
unset table
plot "data" every ::start using 1:2 with lines
如果您需要起始字符串日期,例如作为图例标题,您可以类似地使用额外参数扩展该函数并保留它:
...
startdate="???"
f(x,y,row) = (y>=100 && start==0?(startdate=x,start=row,y):y)
...
plot "data" using 1:(f(stringcolumn(1),,[=11=]))
另一种选择是对绘图命令 using
部分第 2 列中的值应用过滤器。这避免了使用 every
。我个人不喜欢使用 set xdata time
;我更喜欢明确地执行时间转换。例如,这将绘制数据文件中第 2 列中的值大于 100 的部分:
set xrange noextend # limit range to exactly the data points
tf = "%Y-%m-%d"
set xtics time format tf
plot 'data' using ((>100) ? timecolumn(1,tf) : NaN): 2 with linespoints
这会生成您想要的部分数据的图表。 xrange 正好跨越选定的日期。可以通过
检索选择的第一个日期
start_time = strftime(tf, GPVAL_DATA_X_MIN)
print start_time
2020-03-10
用 gnuplot 绘制一些 covid19 数据,我试图找到一种方法来在我的数据集中选择原始数据以将其用作起点。
E. G。我有类似的东西:
#date #cases
2010-03-01 11
2010-03-02 13
2020-03-03 17
2020-03-04 20
2020-03-05 29
2020-03-06 38
2020-03-07 50
2020-03-08 63
2020-03-09 82
2020-03-10 105
2020-03-11 140
2020-03-12 180
2020-03-13 240
...
现在我想找到病例数大于 100 的日期,并将此日期用于 adjust/normalise/whatever 我的所有地块。
所以我要以某种方式找到“2020-03-10 105”行并设置两个变量
start_date = '2020-03-10'
start_index = 11
能够做到
stats <datafile> every ::start_index
set xrange [start_date:]
...
等等等等基本上忽略>100个案例日期之前的所有内容。
我想,可以在我的数据文件的原始数据上使用一些基本的 for+if 循环,但我有点受困于他的方法,因为我找不到一个很好的 example/explanation 如何迭代通过数据文件 raws.
P. S. 当然,我可以使用外部工具来完成此操作,但我宁愿不这样做,因为我正在使用相当多的脚本来收集数据,并希望将所有绘图逻辑保留在我的 gnuplot jinja2 中模板不会使整个内容过于复杂。
我不是 gnuplot 专家,所以这可能不是最好的方法。您可以遍历数据文件两次,一次 "plotting" 将其放入一个虚拟数组,但在每一行调用一个函数 f(y,row)
。该函数获取数据点 (y) 和行号,并设置一个变量 (start) 以在数据点超过 100 时记住该行:
set xdata time
set timefmt "%Y-%m-%d"
start=0
f(y,row) = (y>=100 && start==0?(start=row,y):y)
set table $Data
plot "data" using 1:(f(,[=10=]))
unset table
plot "data" every ::start using 1:2 with lines
如果您需要起始字符串日期,例如作为图例标题,您可以类似地使用额外参数扩展该函数并保留它:
...
startdate="???"
f(x,y,row) = (y>=100 && start==0?(startdate=x,start=row,y):y)
...
plot "data" using 1:(f(stringcolumn(1),,[=11=]))
另一种选择是对绘图命令 using
部分第 2 列中的值应用过滤器。这避免了使用 every
。我个人不喜欢使用 set xdata time
;我更喜欢明确地执行时间转换。例如,这将绘制数据文件中第 2 列中的值大于 100 的部分:
set xrange noextend # limit range to exactly the data points
tf = "%Y-%m-%d"
set xtics time format tf
plot 'data' using ((>100) ? timecolumn(1,tf) : NaN): 2 with linespoints
这会生成您想要的部分数据的图表。 xrange 正好跨越选定的日期。可以通过
检索选择的第一个日期 start_time = strftime(tf, GPVAL_DATA_X_MIN)
print start_time
2020-03-10