gnuplot:绘制数据并使用重复x值的最大值

时间:2014-02-24 12:31:16

标签: plot gnuplot

我想用两列绘制一个巨大数据文件的曲线:

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”值,如果每个日期给出多行。我想在我的情节中绘制每天总和列的最大值。我想每天使用最后/最高给定值。

3 个答案:

答案 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):

enter image description here

有关更详细的说明,请参阅上面的链接答案。

答案 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)

好的,我想这是一个解决方案

  1. 处理未排序的日期
  2. 返回最大值最小值
  3. 仅适用于gnuplot(无外部工具)

一个小缺点:我不知道如何防止来自“统计”的警告。

### 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

将导致:

enter image description here