我想用两列绘制一个巨大数据文件的曲线:
datafile(示例):
#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
如果我使用“plot'data.txt'使用0:1和行”并设置日期格式等,我会得到一个几乎正确的图,但不幸的是它使用“lower / upper”值,如果每个日期给出多行。我想在我的情节中绘制每天总和列的最大值。我想每天使用最后/最高给定值。
答案 0 :(得分:4)
这有点棘手。我对Plotting different columns on the same file using boxes的回答显示了如何对数字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):
有关更详细的说明,请参阅上面的链接答案。
答案 1 :(得分:2)
另一个解决方案可能是下面的代码。假定日期严格是升序或降序,但不是随机的。 公认的解决方案当然是更有效的解决方案,但并非那么容易遵循。 基本思想是将(几个相同日期中的)最后一个日期及其值写入一个新的数据块,并简单地绘制该新数据集。
### 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
答案 2 :(得分:1)
好的,我想这是一个解决方案
一个小缺点:我不知道如何防止来自“统计”的警告。
### 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
将导致: