Reputation: 11
I'm pretty new to this forum.
I have a problem with a gnuplot script. I want the program to read from a file and take the average of the data in a column but just of two subsequent rows.
This is an example of my data file:
10972710;0;97;11699;75114829;14017;62910343;4294966568;71227698;4294690030;17218646
10972710;1;98;4294694062;75242152;4294781521;62921071;4294614770;71144038;4294733461;18276743
10972710;0;99;117245;75164467;4294946663;62862643;49062;71038638;4294745782;17886802
10972710;1;100;4294799584;75123654;4294686842;63040946;4294609337;71224369;4294706709;17333245
10972710;0;101;1845;75045355;46741;62966683;72313;71243339;4294713057;18914555
10972809;1;102;4294963298;75210462;59798;63318000;4587;71262619;70880;19513152
10972809;0;103;4294957708;75074862;33562;63074526;189991;71061923;39240;18642066
For example, focusing on the 4th column I want to perform the average of the 1st row with the 2nd, the 3rd with the 4th and so on. Is there some built-in function in gnuplot or do I have to write my own?
Thank you so much.
Tommaso
Upvotes: 1
Views: 1756
Reputation: 48390
Some simple operations on ajacent rows are possible with gnuplot: You must save the value of one row using an assignment in the using
statement, and the plot only every second point:
set datafile separator ';'
prev = curr = 0
plot 'test.txt' using (int($0)/2):(prev = curr, curr = $4, int($0)%2 == 1 ? (curr - prev)/2.0 : 1/0) with linespoints
The using statement works as follows, first you assign the value of the previous row (which is at that point still in curr
) to the variable prev
, then you assign the value of the current row to curr
and finally do the average if you are on an odd row number (rows start at 0), or give an invalid point with 1/0
.
The result with version 5.0 is
As you see, you get only points although I specified linespoints
. The invalid 1/0
make gnuplot interrupt the lines here, so no lines are plotted.
With gnuplot 5.0 you can save the result of the filtering to a temporary file (or also to a heredoc structure, the $avg
) and plot that processed data with a second call:
set datafile separator ';'
prev = curr = 0
set table $avg
plot 'test.txt' using (int($0)/2):(prev = curr, curr = $4, int($0)%2 == 1 ? (curr - prev)/2.0 : 1/0) with lp pt 7
unset table
set datafile separator whitespace
plot $avg using 1:2 w lp
Note, that this wouldn't work with version 4.6, since this version has a different handling of parsing data files with NaN
inside, like the one which is generated by gnuplot.
Finally, you can also use an external tool like awk
to do the processing for you, like
plot '< awk -F";" "{if (NR%2 == 0) { printf \"%.10e\n\", (\$4-prev)/2.0 }; prev = \$4}" test.txt' using 0:1 with linespoints
Upvotes: 1