gnuplot:绘制数据并使用重复x值的最大值
我想用两列绘制一个巨大数据文件的曲线: 数据文件(示例):gnuplot:绘制数据并使用重复x值的最大值,plot,gnuplot,Plot,Gnuplot,我想用两列绘制一个巨大数据文件的曲线: 数据文件(示例): 如果我使用“plot'data.txt'using 0:1 with lines”并正确设置日期格式等,我将得到一个几乎正确的绘图,但不幸的是,如果每个日期有多行,它将使用“lower/upper”值。我想在绘图中绘制每天总和列的最大值。我想使用每天最后/最高的给定值。这有点棘手。我对的回答显示了如何对数字x轴执行此操作。如果您有时间数据,则必须使用timecolumn(1)而不是$1,仅此而已: reset xval = -1e10
如果我使用“plot'data.txt'using 0:1 with lines”并正确设置日期格式等,我将得到一个几乎正确的绘图,但不幸的是,如果每个日期有多行,它将使用“lower/upper”值。我想在绘图中绘制每天总和列的最大值。我想使用每天最后/最高的给定值。这有点棘手。我对的回答显示了如何对数字x轴执行此操作。如果您有时间数据,则必须使用
timecolumn(1)
而不是$1
,仅此而已:
reset
xval = -1e10
max(x, y) = (x > y ? x : y)
maxval = 0
set timefmt '%Y-%m-%d'
set xdata time
plot 'data.txt' using (val = $2, timecolumn(1)):\
(maxval_prev = (xval == timecolumn(1) ? maxval : 0), \
maxval = (xval == timecolumn(1) ? max(maxval, val) : val),\
xval = timecolumn(1), \
(maxval > maxval_prev ? maxval-maxval_prev : 0)\
) \
smooth frequency lw 3 with linespoints t 'maximum values'
结果如下(见4.6.3):
有关更详细的解释,请参见上面的链接答案。另一个解决方案可能是下面的代码。我们假设日期是严格的升序或降序,但不是随机的。 公认的解决方案当然是更有效的解决方案,但并不容易遵循。 基本思想是将最后一个日期(几个相同的日期)及其值写入一个新的数据块,并简单地绘制这个新数据集
### start code
reset session
$Data <<EOD
#dateYMD sum
2014-02-01 70
2014-02-01 85
2014-02-01 95
2014-02-02 116
2014-02-02 123
2014-02-09 130
2014-02-09 134
2014-02-11 145
EOD
stats $Data nooutput
set table $Dummy
set print $Data2
tmp = ""
do for [i=STATS_records-1:0:-1] {
plot $Data u (a=stringcolumn(1),b=stringcolumn(2),$2) every ::i::i with table
if (tmp ne a) { print sprintf("%s\t%s",a,b); tmp = a}
}
set print
unset table
set xdata time
set timefmt "%Y-%m-%d"
set yrange[0:160]
plot $Data2 u (timecolumn(1)):2 w lp lw 2 pt 7 t "maximum values"
### end code
###开始代码
重置会话
$Data好的,我想这里有一个解决方案
处理未排序的日期
返回最大值和最小值
仅为gnuplot(无外部工具)
一个小缺点:我不知道如何防止来自“stats”的警告
### start code
reset session
# unsorted dates and values
$Data <<EOD
#dateYMD sum
2014-02-01 85
2014-02-09 134
2014-02-01 95
2014-02-02 116
2014-02-01 70
2014-02-02 123
2014-02-09 130
2014-02-11 145
EOD
# get unique dates in seconds
set xdata time
set format x "%s"
set table $DataInSeconds
plot $Data u (timecolumn(1,"%Y-%m-%d")):2 smooth freq
unset table
set xdata # stats will not work with 'xdata time'
stats $DataInSeconds nooutput
UniqueDates = STATS_records
# get the maximum and minimum value per date
set print $MinMaxData
set table $Dummy
do for [i=0:UniqueDates-1] {
plot $DataInSeconds u (a=$1,$1):2 every ::i::i with table
stats [a:a] $Data u (timecolumn(1,"%Y-%m-%d")):2 nooutput
print sprintf("%s\t%g\t%g", strftime("%Y-%m-%d",a), STATS_min_y, STATS_max_y)
}
unset table
set print
print $MinMaxData
# plot the results
set key top left
set yrange[0:160]
set xdata time
set format x "%m/%d"
plot $MinMaxData u (timecolumn(1,"%Y-%m-%d")):3 \
w lp lw 2 pt 7 ps 2 lc rgb "red" t "maximum values",\
'' u (timecolumn(1,"%Y-%m-%d")):2 \
w lp lw 2 pt 6 ps 2 lc rgb "web-green" t "minimum values",\
$Data u (timecolumn(1,"%Y-%m-%d")):2 \
w p lw 2 pt 2 ps 1 lc rgb "blue" t "all values"
### end code
###开始代码
重置会话
#未排序的日期和值
$Data您可以使用awk'{if(date&&date!=$1){print date,val};date=$1;val=$2}'
筛选数据。这将只为每个日期保留最后一个值。@max taldykin此awk脚本将忽略最后一个日期。@hfs,您是对的。我不知道如何在不生成两倍长的代码的情况下解决这个问题。哇,这为我今天节省了很多时间平滑频率
对数据进行排序,所以这是一个假设,它总是有效的,不需要反复迭代所有行。我同意,使用每个
进行循环可能不是很有效。是的,smooth frequency
在“平滑”之后对数据进行排序。如果使用不严格按升序排列的日期测试脚本,将无法获得所需的结果。尽管如此,同一特定日期的值可能是随机的。因此,至少您必须假设日期严格按升序排列,或者首先必须使用外部工具对日期进行排序。
### start code
reset session
# unsorted dates and values
$Data <<EOD
#dateYMD sum
2014-02-01 85
2014-02-09 134
2014-02-01 95
2014-02-02 116
2014-02-01 70
2014-02-02 123
2014-02-09 130
2014-02-11 145
EOD
# get unique dates in seconds
set xdata time
set format x "%s"
set table $DataInSeconds
plot $Data u (timecolumn(1,"%Y-%m-%d")):2 smooth freq
unset table
set xdata # stats will not work with 'xdata time'
stats $DataInSeconds nooutput
UniqueDates = STATS_records
# get the maximum and minimum value per date
set print $MinMaxData
set table $Dummy
do for [i=0:UniqueDates-1] {
plot $DataInSeconds u (a=$1,$1):2 every ::i::i with table
stats [a:a] $Data u (timecolumn(1,"%Y-%m-%d")):2 nooutput
print sprintf("%s\t%g\t%g", strftime("%Y-%m-%d",a), STATS_min_y, STATS_max_y)
}
unset table
set print
print $MinMaxData
# plot the results
set key top left
set yrange[0:160]
set xdata time
set format x "%m/%d"
plot $MinMaxData u (timecolumn(1,"%Y-%m-%d")):3 \
w lp lw 2 pt 7 ps 2 lc rgb "red" t "maximum values",\
'' u (timecolumn(1,"%Y-%m-%d")):2 \
w lp lw 2 pt 6 ps 2 lc rgb "web-green" t "minimum values",\
$Data u (timecolumn(1,"%Y-%m-%d")):2 \
w p lw 2 pt 2 ps 1 lc rgb "blue" t "all values"
### end code