How to apply tail command in gnuplot - gnuplot

I am defining my two colum data file as below in gnuplot file, plot.gnu.
FILE2='case.out'
I want to store the last value of second colum of case.out as Max. I tried as
Max =`(tail -n 2 FILE2 | awk '{print $2}')`
But it gives gives me error
Max =
^
"plot.gnu", line 37: constant expression required
But if I define exact name of file, case.out, instead writing FILE2 in Max command then it works well.
My case.out is something line
3.2853 243.4008
3.2936 243.6239
3.3019 243.8089
3.3103 243.9544
3.3186 244.0590
3.3269 244.1221
3.3353 244.1432
and I want the the Max command should store 244.1432 value.
i.e
print Max
should give 244.1432

Have a look into the manual and or in the gnuplot console type help stats. No need for awk here.
Code:
stats "case.out" u 2 nooutput
print STATS_max
Result:
244.1432
Addition:
Please check the manual about how stats works.
Code:
stats "case.out" u 1:2 nooutput
print STATS_min_x, STATS_max_x
print STATS_min_y, STATS_max_y
Result:
3.2853 3.3353
243.4008 244.1432
Or you can even "rename" the stats results.
Code:
stats "case1.out" u 1:2 nooutput name "First"
print First_min_x, First_max_x
print First_min_y, First_max_y
stats "case2.out" u 1:2 nooutput name "Second"
print Second_min_x, Second_max_x
print Second_min_y, Second_max_y

Related

Creating a command with sprintf. Is this possible?

I want to plot some data. The data is in several files and the line it is in is not always the same. Therefore I used grep and some other commandline tools to extract the line I want. I read online, that it should be possible with gnuplot to print from a string or from the result of a commandline.
I work in linux.
set terminal pdfcairo enhanced font "Garamond,10" fontscale 1.0 size 9in,9in
set nogrid
set samples 1001
set border 31 linewidth .3
set output "access/accessTimeAcrossFreq.pdf"
set xlabel "freq"
set ylabel "Time [s]"
set key right top
set size square
set autoscale y
set termoption lw 2.5
volts = "0.8"
fins = "111 122 222"
freq = "0.5G 1G 1.5G 2G 2.5G 3G"
metrics = "read1bldeltav read0bldeltav read1senseChange read0senseChange read1latchChange read0latchChange sense1speed sense0speed write1CellFlip write0CellFLip write1CellSwing write0CellSwing write1BLSwing write0BLSwing powerpertime"
runTitle = "abetraryString"
filename(fin, f, volt) = sprintf("../%s_temp27_fin%s_freq%s_vdd%s/accessTimeVolLSA/result.txt", runTitle, fin, f, volt)
data(met, file) = system(sprintf("grep -n '%s' %s | cut -d: -f 2 | awk '{$1=$1};1'", met, file))
com(met, file) = sprintf("< grep -n '%s' %s | cut -d: -f 2 | awk '{$1=$1};1'", met, file)
do for [fin in fins] {
do for [v in volts] {
do for [met in metrics] {
set title sprintf("%s VLSA across Freq, fins %s, %sV, w/o she", met, fin, v)
plot for[i=1:words(freq)] com(met, filename(fin, word(freq, i), v)) using (i):2:xtic(word(freq, i)) notitle with points lc i
}
}
}
So I was wondering if a) I can have a function that returns a string that is a command that is then run by gnuplot
b) Where the error might come from:
line 32: warning: Skipping data file with no valid points
line 32: warning: Skipping data file with no valid points
line 32: warning: Skipping data file with no valid points
line 32: warning: Skipping data file with no valid points
line 32: warning: Skipping data file with no valid points
line 32: warning: Skipping data file with no valid points
line 32: x range is invalid
I thought, maybe I need a linebreak at the end of my one-liner of data. Or because gnuplot always thinks the first line is not data... I don't know.
Today I figured it out. I used prints in the for loop to see what the command returns. Before I posted the question I tried the command in a separate terminal with success. The problem was I just tested it with the first element of metrics. The prints revealed that I forgot the metrics need to be all lower case.
To conclude. Yes, you can put a string via a function together and gnuplot will then run it as I was expecting it. See the use of com(..) in the plot line.
Second. I think the xrange error usually points out that in a plot there are no data points and gnuplot does not like a xrange of 0. To figure this out I used prints. I did a quick search if there is a verbose mode but was not successful, so prints it is.
Maybe someone can take away something like I did.

store commented value from data file in gnuplot

I have multiple data files output_k, where k is a number. The files look like
#a=1.00 b = 0.01
# mass mean std
0.2 0.0163 0.0000125
0.4 0.0275 0.0001256
Now I need to retrieve the values of a and b and to store them in a variable, so I can use them for the title or function input etc. The looping over the files in the folder works. But I need some help with reading out the the parameters a and b. This is what i have so far.
# specify the number of plots
plot_number = 100
# loop over all data files
do for [i=0:plot_number] {
a = TODO
b = TODO
#set terminal
set terminal postscript eps size 6.4,4.8 enhanced color font 'Helvetica,20' linewidth 2
set title "Measurement \n{/*0.8 A = a, B = b}"
outFile=sprintf("plot_%d.eps", i)
dataFile=sprintf("output_%d.data", i)
set output outFile
plot dataFile using 1:2:3 with errorbars lt 1 linecolor "red", f(a,b)
unset output
}
EDIT:
I am working with gnuplot for windows.
If you are on a Unixoid system, you can use system to get the output of standard command line tools, namely head and sed, which again allow to extract said values form the files:
a = system(sprintf("head -n 1 output_%i.data | sed \"s/#a=//;s/ b .*//\"", i))
b = system(sprintf("head -n 1 output_%i.data | sed \"s/.*b = //\"", i))
This assumes that the leading spaces to all lines in your question are actually a formatting mistake.
A late answer, but since you are working under Windows you either install the comparable utilities or you might be interested in a gnuplot-only solution (hence platform-independent).
you can use stats to extract information from the datablock (or file) to variables. Check help stats.
the extraction of your a and b depends on the exact structure of that line. You can split a line at spaces via word(), check help word and get substrings via substr() or indexing, check help substr.
Script: (works with gnuplot>=5.0.0)
### extract information from commented header without external tools
reset session
$Data <<EOD
#a=1.00 b = 0.01
# mass mean std
0.2 0.0163 0.0000125
0.4 0.0275 0.0001256
EOD
set datafile commentschar ''
set datafile separator "\t"
stats $Data u (myHeader=strcol(1)[2:]) every ::0::0 nooutput
set datafile commentschar # reset to default
set datafile separator # reset to default
a = real(word(myHeader,1)[3:])
b = real(word(myHeader,4))
set label 1 at graph 0.1,0.9 sprintf("a=%g\nb=%g",a,b)
plot $Data u 1:2 w lp pt 7 lc "red"
### end of script
Result:

How to fix ';' expected error in gnuplot

I am using ubuntu 14.04, gnuplot 4.6 patchlevel 4.
I have the following script, named Plot.script:
## GNUPLOT command file
set terminal postscript color
set style data lines
set noxzeroaxis
set noyzeroaxis
set key top spacing .8
set size ratio 0.821894871074622
set noxtics
set noytics
set title 'Combined DET Plot'
set ylabel 'Miss probability (in %)'
set xlabel 'False Alarm probability (in %)'
set grid
set pointsize 3
set ytics (\
'5' -1.6449, '10' -1.2816, '20' -0.8416, '40' -0.2533, '60' 0.2533, \
'80' 0.8416, '90' 1.2816, '95' 1.6449, '98' 2.0537)
set xtics (\
'.0001' -4.7534, '.001' -4.2649, '.004' -3.9444, '.01' -3.7190, '.02' -3.5401, \
'.05' -3.2905, '.1' -3.0902, '.2' -2.8782, '.5' -2.5758, '1' -2.3263, \
'2' -2.0537, '5' -1.6449, '10' -1.2816, '20' -0.8416, '40' -0.2533)
plot [-4.75343910607888:-0.253347103317183] [-1.64485362793551:2.05374890849825] \
-x title 'Random Performance' with lines 1,\
'tmp/score.det.sub00.dat.1' using 3:2 title 'Term Wtd. fake : ALL Data Max Val=0.267 Scr=0.436' with lines 2,\
'tmp/score.det.sub00.dat.2' using 6:5 notitle with points 2,\
'tmp/score.det.sub01.dat.1' using 3:2 title 'Term Wtd. fake: CTS Subset Max Val=0.267 Scr=0.436' with lines 3,\
'tmp/score.det.sub01.dat.2' using 6:5 notitle with points 3
Then I run gnuplot Plot.script | ps2pdf - .
I get the following error:
line 27: ';' expected
line 27 is the last row of the script:
'tmp/score.det.sub01.dat.2' using 6:5 notitle with points 3
I have searched from web and found this similar question but it doesn't seem to help. Does anyone know what the problem is?
In general it is very hard to debug such a long script, especially without having the test data to run exactly this script. You should start by cutting down your script line by line to track down in which line the error really appears. The whole plot command is treated as a single line, so if it says line 27, the error can also appear earlier.
I guess, that you have the wrong syntax for selecting line types. Using with lines 1 doesn't work, and the simple line
plot x with lines 1
already shows this error. You must use
plot x with lines linetype 1
Accordingly you must fix all other positions where you set a line type (or point type).
line 27: ';' expected
can mean there's a ',' missing in the plot statement. I couldn't find it myself in your code. May be you need to delete blanks before "Scr="
But I had a similar problem.

Gnuplot using stats in for loop

i wanna plot the maximum and average value of different files into one plot.
I got several ntp-stats, so i thought:
input = "./peerstats/s_peerstats.201407"
set terminal svg size 600 400
set xlabel "Day in July (s)"
set ylabel "Jitter (ms)"
set yrange[0:0.65]
set output "ntpq_month_07.svg"
do for [k=10:31]{
stats input.k."_pps" using ($8*1000.0) nooutput name "PPS",\
stats input.k."_rz1" using ($8*1000.0) nooutput name "RZ1",\
stats input.k."_rz2" using ($8*1000.0) nooutput name "RZ2",\
set "ntpq_month_07.svg"
print ($k):PPS_max
print ($k):RZ1_max
print ($k):RZ2_max
print ($k):PPS_mean
print ($k):RZ1_mean
print ($k):RZ2_mean
}
This is the error by gnuplot:
;
stats input.k."_pps" using ($8*1000.0) nooutput name "PPS", stats input.k."_rz1" using ($8*1000.0) nooutput name "RZ1", stats input.k."_rz2" using ($8*1000.0) nooutput name "RZ2", set "ntpq_month_07.svg" ;
print ($k):PPS_max;
print ($k):RZ1_max;
print ($k):RZ2_max;
print ($k):PPS_mean;
print ($k):RZ1_mean ;
print ($k):RZ2_mean;
^
line 20: Expecting [no]output or prefix
Where is the syntax wrong?
Thanks a lot :)!
First you must have all stats commands on a separate line. That works fine. Then it is your print syntax which is broken.
Consider the file test.dat
1
2
and the call
do for [i=10:11] {
stats 'test.dat' using 1 nooutput name "PPS"
stats 'test.dat' using ($1*i) nooutput name "RZ1"
print sprintf("max(PPS_%d): %f", i, PPS_max)
print sprintf("max(RZ1_%d): %f", i, RZ1_max)
}
gives the output
max(PPS_10): 2.000000
max(RZ1_10): 20.000000
max(PPS_11): 2.000000
max(RZ1_11): 22.000000
So your script should look as follows:
input = "./peerstats/s_peerstats.201407"
set terminal svg size 600 400
set xlabel "Day in July (s)"
set ylabel "Jitter (ms)"
set yrange[0:0.65]
set output "ntpq_month_07.svg"
do for [k=10:31]{
stats input.k."_pps" using ($8*1000.0) nooutput name "PPS"
stats input.k."_rz1" using ($8*1000.0) nooutput name "RZ1"
stats input.k."_rz2" using ($8*1000.0) nooutput name "RZ2"
set "ntpq_month_07.svg"
print sprintf('%d: %f', k, PPS_max)
print sprintf('%d: %f', k, RZ1_max)
print sprintf('%d: %f', k, RZ2_max)
print sprintf('%d: %f', k, PPS_mean)
print sprintf('%d: %f', k, RZ1_mean)
print sprintf('%d: %f', k, RZ2_mean)
}
Of course your svg files don't contain any output, because you don't plot anything.

Plotting arrows with gnuplot

I have data generated in a simulation. The generated data file looks something like this:
1990/01/01 99
1990/01/02 92.7
1990/01/03 100.3
1990/01/04 44.2
1990/01/05 71.23
...
2100/01/01 98.25
I can create a chart (trivially), by simply issuing the (long versioned) command:
plot "simulation.dat" using 1:2 with line
I want to add a third column which will add arrow information. The encoding for the third column would be as follows:
0 => no arrow to be drawn for that x axis value
1 => an UPWARD pointing arrow to be drawn for the x axis value
2 => a DOWNWARD arrow to be drawn for the x axis value
I am just starting to learn gnuplot, and will appreciate help in how I can use gnuplot to create the arrows on the first plot?
I dont think there is an automatic way to create all your arrows at the same time based on the third column. You will have to execute the following for each arrow that you want:
set arrow xval1,yval1 to xval2,yval2
You can also use relative arrows
set arrow xval1,yval1 rto 1,0
This will draw a horizontal arrow from xval1,yval1 to (xval1+1),yval1
There are plenty of options associated with the set arrow command:
If you didn't want the arrow head then you might try the impulses style (with impulses rather than with lines)
(If you still want the lines on top then you can plot twice).
If you really want the arrow heads then the following might help: It uses a for loop (or sorts) to add vertical arrows to a plot.
Gnuplot script, for loop within or adding to existing plot
Specifically:
create a file simloop.gp which looks like the following:
count = count+1
#save the count to count.gp
system 'echo '.count.' > count.gp'
#load the simloop shell
system "./simloop.sh"
#draw the arrow
load 'draw_arrow.gp'
if(count<max) reread
Then create a simloop.sh file that looks something like so
#!/bin/bash
#read the count
count=$(awk -F, '{print $1}' count.gp)
#read the file
xcoord=$(awk -v count=$count -F, 'BEGIN{FS=" ";}{ if(NR==count) print $1}' simulation.dat)
ycoord=$(awk -v count=$count -F, 'BEGIN{FS=" "}{ if(NR==count) print $2}' simulation.dat)
dir=$(awk -v count=$count -F, 'BEGIN{FS=" "}{ if(NR==count) print $3}' simulation.dat)
#choose the direction of the arrow
if [ \"$dir\" == \"0\" ]; then
echo '' > draw_arrow.gp
fi
if [ \"$dir\" == \"1\" ]; then
echo 'set arrow from ' $xcoord' ,0 to '$xcoord','$ycoord' head' > draw_arrow.gp
fi
if [ \"$dir\" == \"2\" ]; then
echo 'set arrow from '$xcoord',0 to '$xcoord','$ycoord' backhead' > draw_arrow.gp
fi
Then create a simulation.gp file that looks something like so:
count = 0;
max = 5;
load "simloop.gp"
set yrange[0:*]
plot "simulation.dat" u 1:2 w l
Make sure the shell file has executable permissions (chmod +wrx simloop.sh), load up gnuplot and type
load "./simulation.gp"
This worked for me with the data file
1 99 0
2 92.7 1
3 100.3 2
4 44.2 0
5 71.23 1
(For testing I got rid of the time formatting You should be able to put it back without too much trouble.)
Then I got this graph:
Which I think is more or less what you want.
Although the question is quite old, here is my answer.
One can use the vectors plotting style, which can use variable arrowstyles based on a column's value:
set style arrow 1 backhead
set style arrow 2 head
set yrange[0:*]
set xdata time
set timefmt "%Y/%m/%d"
plot "simulation.dat" using 1:2 with line,\
"" using 1:2:(0):(-$2):($3 == 0 ? 1/0 : $3) with vectors arrowstyle variable
It the value of a column is 1/0, the point is considered as undefined and is skipped.

Resources