Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Plotting Average curve for points in gnuplot

[Current]

I am importing a text file in which the first column has simulation time (0~150) the second column has the delay (0.01~0.02).

1.000000 0.010007
1.000000 0.010010
2.000000 0.010013
2.000000 0.010016
.
.
.
149.000000 0.010045
149.000000 0.010048
150.000000 0.010052
150.000000 0.010055

which gives me the plot: Instantanous Delay in Seconds


[Desired]

I need to plot an average line on it like shown in the following image with red line:

Average red line

like image 302
saif Avatar asked Mar 17 '17 10:03

saif


2 Answers

Here is a gnuplot only solution with sample data:

set table "test.data"
set samples 1000
plot rand(0)+sin(x)
unset table

You should check the gnuplot demo page for a running average. I'm going to generalize this demo in terms of dynamically building the functions. This makes it much easier to change the number of points include in the average.

This is the script:

# number of points in moving average
n = 50

# initialize the variables
do for [i=1:n] {
    eval(sprintf("back%d=0", i))
}

# build shift function (back_n = back_n-1, ..., back1=x)
shift = "("
do for [i=n:2:-1] {
    shift = sprintf("%sback%d = back%d, ", shift, i, i-1)
} 
shift = shift."back1 = x)"
# uncomment the next line for a check
# print shift

# build sum function (back1 + ... + backn)
sum = "(back1"
do for [i=2:n] {
    sum = sprintf("%s+back%d", sum, i)
}
sum = sum.")"
# uncomment the next line for a check
# print sum

# define the functions like in the gnuplot demo
# use macro expansion for turning the strings into real functions
samples(x) = $0 > (n-1) ? n : ($0+1)
avg_n(x) = (shift_n(x), @sum/samples($0))
shift_n(x) = @shift

# the final plot command looks quite simple
set terminal pngcairo
set output "moving_average.png"
plot "test.data" using 1:2 w l notitle, \
     "test.data" using 1:(avg_n($2)) w l lc rgb "red" lw 3 title "avg\\_".n

This is the result:

moving average

The average lags quite a bit behind the datapoints as expected from the algorithm. Maybe 50 points are too many. Alternatively, one could think about implementing a centered moving average, but this is beyond the scope of this question. And, I also think that you are more flexible with an external program :)

like image 155
maij Avatar answered Sep 29 '22 04:09

maij


Edit

The updated question is about a moving average.

You can do this in a limited way with gnuplot alone, according to this demo.

But in my opinion, it would be more flexible to pre-process your data using a programming language like python or ruby and add an extra column for whatever kind of moving average you require.

The original answer is preserved below:


You can use fit. It seems you want to fit to a constant function. Like this:

f(x) = c

fit f(x) 'S1_delay_120_LT100_LU15_MU5.txt' using 1:2 every 5 via c

Then you can plot them both.

plot 'S1_delay_120_LT100_LU15_MU5.txt' using 1:2 every 5, \
f(x) with lines

Note that this is technique can be used with arbitrary functions, not just constant or lineair functions.

like image 23
Roland Smith Avatar answered Sep 29 '22 03:09

Roland Smith