Gnuplot: operations with data in different blocks - gnuplot

I have a data file consisting of two blocks (separated by a single blank line) and would like to plot the difference between data from block 1 and block 2, i.e., something like
plot 'a.dat' using 1:($2_1-$2_2)
where $2_1 is supposed to mean "data from block 1, col.2" and $2_2 "data from block 2, col.2". Is that possible within Gnuplot, and if so, how?
Thanks,
Tom

This task is most likely not possible directly in Gnuplot, however, one can preprocess the data file first, using, e.g., gawk and then plot the modified file. For example:
dataFile="a.dat"
plotCmd(fname)=sprintf("<gawk '\
BEGIN{mode=0;l=0;} \
mode==0{if(NF==0){mode=1;}else{x[NR]=$1;y[NR]=$2;}} \
mode==1{if(NF>0){mode=2;l=NR;}} \
mode==2{print $1,y[NR-l+1],$2}' %s", fname)
plot plotCmd(dataFile) u 1:($2-$3) w l
The gawk script reads the file and saves the first and second column into arrays x and y until it reaches a blank line (zero number of fields). Then it skips all consecutive blank lines until it reaches a non-empty line (NF>0). It remembers the position of this line in the input file and then outputs for each line in the second block the x-coordinate together with the corresponding y-coordinate from the first block, i.e., a data file such as
1 2
2 4
3 6
1 4
2 8
3 12
would be transformed into
1 2 4
2 4 8
3 6 12
This assumes that the x-coordinates in both blocks match...

Related

Gnuplot, simple xy graph, bug?

I have a file called plot.txt with a number of values such as:
1 7.5000000000000000
2 10.312500000000000
3 11.660156250000000
4 12.425537109375000
5 12.913055419921875
6 13.248996734619141
7 13.493841290473938
8 13.679883163422346
9 13.825851876754314
10 13.943356417876203
This list continuous until about 450. When i try to plot it with lines i get a linear line across the graph. Why is this? line graph And how do I get rid of it?
open(newunit=write_unit,access='sequential',file='plotgnu.txt',status='unknown')
write(write_unit,*)'plot ''plot.txt'' with linespoints '
close(write_unit,status='keep')
!Kaller på gnuplot
call execute_command_line("gnuplot -persist plotgnu.txt")
When i plot it without linespoints I get the the correct graph just with points point graph
write(write_unit,*)'plot ''plot.txt'' '
Your data file contains the same data set four times without empty lines:
1 7.5000000000000000
2 10.312500000000000
...
437 14.999999999999998
438 14.999999999999998
1 7.5000000000000000
2 10.312500000000000
...
If you plot that with lines you do of course also get a line from the last point of the first "data set" to the first point of the second occurrence of the data set. And that is the line you are seeing.

Plotting datafile with abbreviated values with gnuplot

I have a gnuplot datafile that looks like this:
1 4810 582 573 587
2 99k 67k 56k 40k
3 119k 82k 68k 49k
4 119k 81k 68k 49k
5 120k 81k 65k 45k
6 121k 82k 65k 44k
7 124k 106k 97k 86k
8 128k 134k 131k 131k
9 128k 130k 131k 135k
10 129k 133k 130k 132k
First column will be on the X-axis labeled as "Time", the rest are the different interrupt values with respect to time (i.e. IRQ1, IRQ2, IRQ3, IRQ4)
The problem when generating a plot with this is that gnuplot does not seem to interpret the abbreviated values with the K suffix as numbers in the thousands, but instead as raw values such as 99, 67, 119, etc. Thus the lines will jump from around 5000 at time 1 and drop to around 100 in the graph.
Are there any options to tell gnuplot to automatically interpret abbreviated values and plot them accordingly?
I think there is no direct way of telling gnuplot of how to interpret the input in this case.
You can, however, write your own function that converts the string-input to numbers
check(x)=(pos=strstrt(x,"k"),\
pos > 0 ? real(substr(x,1,pos-1))*1000 : real(x))
The function check first determines the position of the letter 'k' in the input. (The function strstrt returns '0' if the input x does not contain the letter 'k'.)
If the input contains the letter 'k', take the input, discard the last letter, convert the remaining part to a number and multiply it by 1000.
If the input does not contain 'k', return the input
Now you can plot the data file (assuming its name is test):
plot 'test' u 1:(check(stringcolumn(2))) w l
This should do the job!
a non-purely gnuplot, unix solution would use process substitution:
plot "<(sed 's/k/000/g' datafile.dat)" u 1:2 w lp
The sed 's/k/000/g' command replaces all occurrences of the character k with 000 in datafile.dat: e.g. 96k will be replaced with 96000.
The output is similar to the plot posted by #Knorr

Plotting multiple graphs depending on column value with gnuplot

I have the following data, which I wan't to plot using GNUPLOT:
#TIME #VALUE #SOURCE
1 100 A
1 88 B
2 115 A
2 100 B
3 130 A
3 210 B
I want to have two lines drawn, depending on the value of column #SOURCE. One line for A and one line for B. Is this possible with GNUPLOT and if yes how?
Is it possible to also draw a summation of column #VALUE depending over column #TIME? Means, that for all equal entries in #TIME, the values in #VALUE will be summed up.
Thanks in advance,
Frank
One way to do it would be to use grep to locate lines ending with A or B and plot the result. You can do this in a single plot line with a for loop if you know the characters lines will end in:
plot for [s in 'A B'] sprintf("<(grep -v '%s$' data.dat)", s) u 1:2 w l
This plots the data you provided (saved in data.dat) as two different lines.
You could also change the for part to [s in 'word1 word2 word3'] or any other string you like. If you don't know the character/word lines will be ending with you would probably need to pass the file twice first to determine the string for the for loop and a second time to do the plotting.

How to plot piecewise function using data plot in Gnuplot?

According to figure above. this picture is generated from data points in text file. My question is that how can i remove the line at any two points if graph is jumped? (In my picture see that graph is jump about on x~260)
note that my purpose is that i just want to make this graph look like piecewise function that mean line on the middle of graph should not be connected because is jumped.
In gnuplot you can split a line in several parts either when you have an invalid data value somewhere, or an empty line.
For the first situation, you could check inside the using statement, if the difference to the previous point is too large, and invalidate the current point. But that would also make you loose not only the connecting line, but also the first point after the jump:
lim=3
y2=y1=0
plot 'test.dat' using (y2=y1,y1=$2,$1):($0 > 0 && abs(y2-y1) > lim ? 1/0 : y1) with linespoints
The test data file I used is
1 1
2 1.1
3 0.95
4 1
5 5
6 6
7 5.5
8 5.8
9 -2
10 -2.5
11 -4
As you see, the points at x=5 and x=9 are lost.
Alternatively, you can pipe your data through an external tool like awk for the filtering. In this case you can insert an empty line when the difference between two consecutive y-values exceeds some limit:
filter(lim) = 'awk ''{if(NR > 1 && sqrt((y-$2)**2) > '.lim.') print ""; print; y=$2}'' test.dat'
plot '< '.filter(3) using 1:2 with lines
Note, that I used the sqrt((..)**2) only to simulate an abs function, which awk doesn't have.

gnuplot: How to plot each line of a data file as Y and incremental X

I have a data file containing 30 columns and N rows. Each rows correspond to 30 values of function f(x) for x={1,...,30}. The data file has following pattern:
#<index> f(1) f(2) ... f(30)
1 7.221 5.302 ... -1.031
2 4.527 3.193 ... 0.410
...
N 6.386 1.321 ... -0.386
gnuplot interprets first column as X and the second one as Y. But, what I want is to plot each line in a separated output file without transposing this data file. For example, for the first line, the desired output would be what gnuplot gets with this input file:
# X Y
1 7.221
2 5.302
...
30 -1.031
I found a solution:
plot "data.dat" matrix every 1::1 with linespoint
matix indicates data file type by which the input file interpreted as matrix.
every 1::1 skip the first column
UPDATED based on #Christoph's comment:
plot for [i=2:30] 'data.dat' using (i-1):(column(i)) with linespoint

Resources