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.
Related
I want to read multiple png files - which themselves were created with gnuplot (terminal png) - in order to achieve an "overlay" - that is, a number of functions plotted together one on top of the other, with no background. This apparently could be done with gnuplot in one session.
I found this idea from the Linux Gazette article "Plotting the spirograph equations with 'gnuplot' ", from 2006 :
https://linuxgazette.net/133/luana.html
I am stuck on a number of error messages (vide infra) :
line 0: Bad data on line 1 of file [...]
line 0: warning: using default binary record/array structure
line 0: Too many using specs for this style
Looking for solutions, I read in the help pages ( http://gnuplot.info/docs_5.5/loc7742.html ) that gnuplot can read png images :
plot 'file.png' binary filetype=png
... and I have looked into using pngcairo instead of png itself. I am using eog to view the .png images. Here is sample code which generates the error above, and more if adjusted :
set size ratio -1
set nokey
set noxtics
set noytics
set noborder
set parametric
i2p = {0,1}*2*pi
set terminal png
t0 = 0
t1 = 1
#---------------------------------------------
# plot first function in the gnuplot session :
#---------------------------------------------
test01(t) = exp(i2p*(2*t))
set output "solve_png_problem_15nov22a.png"
plot [t=t0:t1] 1*real(test01(t)),1*imag(test01(t)) lc 1
#---------------------------------------------------
# plot second function in the same gnuplot session :
#---------------------------------------------------
test02(t) = + 3*1.0**20 * exp(i2p*(-3*t+20/200. )) + 3*1.0**19 * exp(i2p* (2*t+20/200.))
set output "solve_png_problem_15nov22b.png"
plot [t=t0:t1] 1*real(test02(t)),1*imag(test02(t)) lc 2
#------------------------------------------------------------
# last plotting to apparently "overlay" the two plots above :
#------------------------------------------------------------
set terminal png size 600,600
set output "solve_png_problem_15nov22_overlay.png"
set noparametric
plot "solve_png_problem_15nov22a.png", "solve_png_problem_15nov22b.png"
.... the reduced sample code is generated from the awk script supplement to the article - see it for detail :
https://linuxgazette.net/133/misc/luana/spirolang.awk.txt
The functions are nontrivial so they were kept in tact, as the associated settings might be causing the problem. The individual images look ok, so I think the problem is in the last plot command.
I read in the help pages that gnuplot can read png images :
plot 'file.png' binary filetype=png
... and also filetype=auto, and I have looked into using pngcairo instead of png itself, with no progress ; I have read the results of Google searches for the error messages. I have read the help pages on terminal, png, image, binary, and so on. I was expecting gnuplot to simply recognize the file was a png image that gnuplot itself generated, using the png terminal. What actually results is the error"Too many using specs for this style". For this, I have tried moving the position of the "binary filetype=png" in the code, which give the error "line 0: Bad data on line 1 of file [...]". I have also tried using programs outside gnuplot, such as montage and composite (ImageMagick).
gnuplot version 5.4 patchlevel 2
Ubuntu 22.04
post-answer update:
TL;DR : use svg terminal.
I saved a lot of grief by simply using the svg terminal. The original work must have been published before gnuplot got the svg terminal. I still need to work svg into the original script - but svg will make it a lot easier.
Try this in GNUPLOT.
gnuplot<<EOF
set terminal png medium size 600,600 background rgb "white"
set size ratio -1
set nokey
set noxtics
set noytics
set noborder
set parametric
i2p = {0,1}*2*pi
t0 = 0
t1 = 1
#---------------------------------------------
# plot first function in the gnuplot session :
#---------------------------------------------
test01(t) = exp(i2p*(2*t))
set output "solve_png_problem_15nov22a.png"
plot [t=t0:t1] 1*real(test01(t)),1*imag(test01(t)) lc 1
#---------------------------------------------------
# plot second function in the same gnuplot session :
#---------------------------------------------------
test02(t) = + 3*1.0**20 * exp(i2p*(-3*t+20/200. )) + 3*1.0**19 * exp(i2p* (2*t+20/200.))
set output "solve_png_problem_15nov22b.png"
plot [t=t0:t1] 1*real(test02(t)),1*imag(test02(t)) lc 2
#------------------------------------------------------------
# last plotting to "overlay" the two plots above :
#------------------------------------------------------------
set output "solve_png_problem_15nov22_overlay.png"
plot \
[t=t0:t1] 1*real(test01(t)),1*imag(test01(t)) lc 1, \
[t=t0:t1] 1*real(test02(t)),1*imag(test02(t)) lc 2
EOF
First Result:
Second Result:
Combined Result:
For the following data.dat file:
08:01:59 451206975237005878
08:04:07 451207335040839108
08:05:56 451207643872368805
08:07:49 451207961547842270
08:09:56 451208317883903787
08:10:12 451208364811411904
08:14:09 451209030026853864
08:16:19 451209395116787156
08:17:14 451209552481002386
08:20:22 451210080432357203
08:25:36 451210963309583903
08:30:23 451211772783766177
08:34:04 451212394854723707
08:35:53 451212702239472024
08:48:46 451214876715294857
08:49:56 451215072475511660
08:51:24 451215321890488523
08:52:39 451215533925588479
08:52:42 451215542324801784
08:54:30 451215845971562410
08:55:08 451215951262906948
08:58:30 451216519498960432
I'd like to draw a horizontal line at the specific level (e.g. 451211772783766177). However, the number is too large to process.
Here is my attempt (based on this post):
$ gnuplot -p -e 'set arrow from 451211772783766177 to 451211772783766177; plot "data.dat" using 2 with lines'
which gives the following error:
line 0: warning: integer overflow; changing to floating point
How I should proceed?
I would treat your large number as a constant function, and plot it right after your data. Also, writing it on a exponential notation X.XE+YY = X.X times 10 to the +YY power (more info on format specifiers here) also takes care of the error:
plot "data.dat" using 2 with lines, 4.51211772783766177E17 with lines
Let me know if this works!
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.
I have a shell script that performs some calculations and plot the results. I have used gnuplot for plotting the results. I'm facing two problems. I used to run the script on my cygwin and it's Okay. When I tried to run it on Ubuntu (Version 10.04-wubi-version), it couldn't recognize the png files (set terminal png unknown). I have tried to install (missing libraries that support "libgd2_2.0.36~rc1~dfsg" and update the libraries.... no luck !! then I have decided to use set terminal pdf instead since I found it supported :
here is my gnuplot version:
G N U P L O T
Version 4.4 patchlevel 0
last modified March 2010
System: Linux 2.6.35-32-generic
here is the output of terminal types:
latex LaTeX picture environment
mf Metafont plotting standard
mif Frame maker MIF 3.00 format
mp MetaPost plotting standard
nec_cp6 NEC printer CP6, Epson LQ-800 [monocrome color draft]
okidata OKIDATA 320/321 Standard
pbm Portable bitmap [small medium large] [monochrome gray color]
pcl5 HP Designjet 750C, HP Laserjet III/IV, etc. (many options)
-->pdf PDF (Portable Document File) file driver
postscript PostScript graphics, including EPSF embedded files (*.eps)
pslatex LaTeX picture environment with PostScript \specials
pstex plain TeX with PostScript \specials
Now, After I have modified the shell script to use pdf, I'm getting this error (Note: some of the pdf files are created ).
line 0: ';' expected
Again, I've added ';' to all of the lines.... and the error still appears.
Here is part of my shell script (that gives the error):
gnuplot << TOEND ;
set terminal pdf;
set output 'A.pdf';
set autoscale ;
#unset log
#unset label
set xtic auto ;
set ytic auto ;
set title "title";
set xlabel "x axis";
set ylabel "y axis";
######################################
#UPDATE: I have added double space to a void the error
######################################
plot "A1.tr" using 1:2 title "A" with lines 9, \
"A2.tr" using 1:2 title "B" with lines 11
the output (Note this part is not of the created pdf files):
line 0: invalid character \ --->pointing to 9, \
line 0: invalid command --->poiting to A2.tr
the rest of shell script produces the same error (Note: output is created)
......
......
######################################
#UPDATE: #psibar pointed that 'ls' missing
######################################
plot "results.tr" using 1:2 title "Results" with lines ls 9;
^
line 0: ';' expected---> pointing to 9 ;
After long searching, I think the problem has to do with version of UBUNTU and Gnuplot....I don't want to upgrade my version of ubuntu.....
After solving the errors. Any suggestions on how to get the "set terminal png" works on ubuntu 10.04 ??
To solve the problem I have added ls and double spaces after the 9, \.
The final answer would be :
gnuplot << TOEND ;
set terminal pdf;
set output 'A.pdf';
set autoscale ;
#unset log
#unset label
set xtic auto ;
set ytic auto ;
set title "title";
set xlabel "x axis";
set ylabel "y axis";
######################################
#UPDATE: I have added double space to a void the error
# and #psibar pointed that 'ls' was missing
######################################
plot "A1.tr" using 1:2 title "A" with lines ls 9, \
"A2.tr" using 1:2 title "B" with lines 11
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.