How can I skip empty lines in gnuplot - gnuplot

I would like to plot below file using gnuplot with a continues line. the problem is that there is a empty line after each point. I can get a graph with points. Could you please help me?
x y type
0 -1866.47 i
100 -1866.52 i
200 -1867.11 i
300 -1868.78 i
400 -1871.58 i
500 -1875.4 i
600 -1880.12 i
700 -1885.62 i
800 -1891.81 i
900 -1898.63 i
1000 -1906.02 i
1100 -1913.94 i
1200 -1922.33 i
1300 -1931.17 i
1400 -1940.43 i
1500 -1950.08 i
1600 -1960.11 i
1700 -1970.49 i
1800 -1981.22 i
1900 -1992.27 i
2000 -2003.63 i

You can filter out the file using an external command. E.g, in a *nix OS, you can use awk:
plot "< awk 'NF!=0 { print $0 }' file.dat" w l
(in awk syntax, NF gives the number of fields in a given line, and $0 contains the entire line)

You can cheat with splot :D
set ticslevel 0
set view 90,0
unset ytics
set xtics offset 0,-1
splot 'empt.txt' u 1:1:2 w l t 'title'

A rather late answer, but already from gnuplot 5.0.0 on (2015), you have the plotting style with table (check help with table). So, you can do it without external tools (platform-independently) and without splot-"cheating".
Simply plot your file (or datablock) in a datablock (or file) which will remove the empty lines.
Script:
### remove empty lines in data
reset session
$Data <<EOD
x y type
0 -1866.47 i
100 -1866.52 i
200 -1867.11 i
300 -1868.78 i
400 -1871.58 i
500 -1875.4 i
600 -1880.12 i
700 -1885.62 i
800 -1891.81 i
900 -1898.63 i
1000 -1906.02 i
1100 -1913.94 i
1200 -1922.33 i
1300 -1931.17 i
1400 -1940.43 i
1500 -1950.08 i
1600 -1960.11 i
1700 -1970.49 i
1800 -1981.22 i
1900 -1992.27 i
2000 -2003.63 i
EOD
set table $NoEmptyLines
plot $Data u 1:2 w table
unset table
plot $NoEmptyLines u 1:2 w l lc rgb "red"
### end of script
Result:

Related

Marking zero values with a red line in gnuplot

I have a .csv datafile that outputs values from 0 to 500 i.e
25.2
2.82
2.05
2.13
2.42
2.17
2.00
0
0
0
0
3.33
3.41
3.26
3.30
0
27.8
and plot it using
plot 'out.csv' using 1 with lines
From that file I would like any 0 values to be marked on the graph with a single red line
Depending on what exactly you are looking for, the following would be my suggestion from what I understood from your question.
Plot the data again with impulses and filtered with the ternary operator (check help ternary).
Script:
### plot with ternary operator
reset session
# create some random test data
set samples 300
set table $Data
plot '+' u (rand(0)<0.97 ? (rand(0)**20)*500+1 : 0) w table
unset table
set key out
plot $Data u 1 w l lc 1 ti "data", \
'' u ($1==0 ? 500 : NaN) w impulses lc "red" ti "0 value"
### end of script
Result:

Gnuplot filledcurves flip axes

There is a style to fill the space between two functions of x.
Examples of such plots can be found e.g. at http://gnuplot.sourceforge.net/demo/fillbetween.html
Is there any way to make similar plot, but with flipped x and y axes?
Here is the desired shape of a curve (without rotated/mirrored labels, titles and legends, of course)...
It could be done with closed contour (like last example here http://www.gnuplot.info/demo_svg_cvs/fillcrvs.html), but this would require reshuffling the data file. Any other options?
Thank you!
You can't do this directly. From help filledcurves:
The third variant fills the area between two curves sampled at the same set of
x coordinates. It requires three columns of input data (x, y1, y2).
I don't think you can specify (y, x1, x2) directly. As a workaround you can the area between the y axis and the larger function in some color, and then fill the area between the y axis and the smaller function in white:
x1(y) = cos(y)+1
x2(y) = cos(y)+2
xmax(y) = (x1(y) > x2(y) ? x1(y) : x2(y))
xmin(y) = (x1(y) < x2(y) ? x1(y) : x2(y))
plot '+' using (xmax($1)):1 with filledcurve y1, \
'+' using (xmin($1)):1 with filledcurve y1 fillcolor rgb "white"
This probably has to be tweaked a little if one or both of the two functions can be negative.
With gnuplot >=5.2 it could be tweaked even further because it allows arrays.
The following code shows a workaround how filled curves between vertically oriented curves can be realized. You can even use transparency. If you download the attached PNG you will notice that it actually has a transparent background. The basic idea behind this workaround is to make closed areas and fill them. For this, you need to reverse one border, concatenate the borders and plot them filled. Unfortunately, gnuplot has no function to reverse datapoints in a column, so you have to do it in a special procedure yourself.
The code:
### "Vertical" filledcurves
reset session
# create some dummy data
N = 50
set samples N
set xrange [-5:5]
set table $Data
plot '+' u (sin($1)):1:(rand(0)*0.3+1) with table
unset table
# put Borders into arrays
stats $Data nooutput
RowCount = STATS_records
array BorderX1[RowCount]
array BorderX2[RowCount]
array BorderY[RowCount]
set table $Dummy
plot $Data u (BorderX1[$0+1]=$1-$3):(BorderX2[$0+1]=$1+$3):(BorderY[$0+1]=$2) with table
unset table
# reverse BorderX2 and merge borders
set samples RowCount
set table $Border
plot '+' u (BorderX1[$0+1]):(BorderY[$0+1]) with table
plot '+' u (BorderX2[RowCount-$0]):(BorderY[RowCount-$0]) with table
unset table
# make the plot
set object 1 rect at 0,-3 size 10,0.5 fs solid 1.0 fc rgb "black" back
set yrange[-5:5]
plot \
$Border u 1:2 w filledcurves fc rgb "#AA00FF00" not,\
$Border u ($1*1.5):2 w filledcurves fc rgb "#AAFFFF00" not,\
$Data u ($1+2.5):2 w filledcurves y2 fc rgb "brown" not,\
$Data u 1:2 w l lw 8 lc rgb "blue" not,\
'+' u 1:(cos($1)-0.5):(cos($1)+0.5) w filledcurves lc rgb "grey" not,\
'+' u 1:(cos($1)):(1) w l lw 3 dt 2 lc rgb "white" not
### end of code
The result:
Update: These are two alternative and simpler approaches compared to my first answer. One of them works even with gnuplot 5.0.
The plotting style filledcurves (so far) can only fill between two y-curves with identical x-values. However, gnuplot can fill closed curves. So, make the curve closed. Like in my first answer, you can do this if you reverse one curve and add it to the other one.
The assumption for both scripts is that the data has a common y-column, i.e. is organized in 3 columns, e.g. here: y x1 x2
Data: SO50676753.dat (same as OP's data, from silver.dat in the gnuplot demo directory)
# y x1 x2
10 280 16.7332
20 191 13.8203
30 152 12.3288
40 150 12.2474
50 104 10.1980
60 77 8.7750
70 69 8.3066
80 60 7.7460
90 60 7.7460
100 51 7.1414
110 41 6.4031
120 34 5.8310
130 35 5.9161
140 34 5.8310
150 24 4.8990
160 24 4.8990
170 19 4.3589
180 21 4.5826
190 20 4.4721
200 18 4.2426
210 21 4.5826
220 15 3.8730
230 19 4.3589
240 12 3.4641
250 20 4.4721
260 20 4.4721
270 18 4.2426
280 18 4.2426
290 20 4.4721
300 12 3.4641
310 26 5.0990
320 17 4.1231
330 8 2.8284
340 6 2.4495
350 8 2.8284
360 10 3.1623
370 20 4.4721
380 14 3.7417
390 8 2.8284
400 10 3.1623
410 9 3.0000
420 8 2.8284
430 10 3.1623
440 13 3.6056
450 9 3.0000
460 5 2.2361
470 7 2.6458
480 11 3.3166
500 7 2.6458
510 9 3.0000
520 12 3.4641
530 4 2.0000
540 7 2.6458
550 10 3.1623
560 9 3.0000
580 8 2.8284
590 9 3.0000
600 5 2.2361
Script 1: (works with gnuplot>=5.0.0)
Here you assume that you have monotonic and unique y-values. With this you can use the option smooth unique (available at least in gnuplot 4.x versions) to reverse one curve. However, since this solution here uses datablocks and plotting style with table it requires at least gnuplot 5.0.0. Maybe with some workarounds and temporary files you can also get it to work with some 4.6 versions.
### fill between vertical curves
reset session
FILE = "SO50676753.dat"
set table $Temp
plot FILE u 1:2
plot FILE u (-$1):3 smooth unique
set table $Data
plot $Temp u 2:1 index 0 w table, \
'' u 2:(-$1) index 1 w table
unset table
set style fill solid 0.3
set grid x,y
plot $Data u 1:2 w filledcurves
### end of script
Script 2: (works with gnuplot>=5.2.0)
With this solution there are no special assumptions about the data, but since it uses indexing of datablocks it requires gnuplot>=5.2.0.
### fill between vertical curves
reset session
FILE = "SO50676753.dat"
set table $Temp1
plot FILE u 2:1 w table
set table $Temp2
plot FILE u 3:1 w table
unset table
set print $Data
do for [i=1:|$Temp1|] { print $Temp1[i] }
do for [i=|$Temp2|:1:-1] { print $Temp2[i] } # reverse data
set print
set style fill solid 0.3
set grid x,y
plot $Data u 1:2 w filledcurves
### end of script
Result: (same for both scripts):

Gnuplot plot points in certain interval with autoupdate

Say, I have a large data file that starts at index 1 and ends at more than 10000, like this:
1 -35000 44312 53750 97500 67687 5000 1.64
2 33500 -12937 -68000 -37250 -35937 -96750 1.64
3 -37750 43125 53500 95250 66937 4500 1.64
4 29000 -15437 -69000 -39750 -36562 -97250 1.64
5 -39000 43062 52250 93000 65750 3750 1.64
.
.
.
100000 29250 -14250 -69250 -41500 -37500 -98000 1.64
I use this command to monitor the data online:
plot 'data.raw' using 0:3 title 'Reference' w lp ls 1, \
'data.raw' using 0:7 title 'Temperature' w lp ls 7
set xrange [0: ]
pause 0.5
replot
reread
As the data points increases, I barely see a change in the graph, because I plot the whole file from X=0. How can I plot a certain interval only, e.g. deltaX = 300 points with autoupdate? So I would then see practically 0-300, 300-600, and so on in plot window of Gnuplot.
Thank You!
Not sure if this is what you're after. Say that I have some data file with 1000 entries (generated with bash):
for i in `seq 1 1 1000`; do echo $i $RANDOM >> data; done
Now I plot in intervals of 100 points and visualize each interval during 2 second:
do for [i=1:10] {
set xrange[100*(i-1):100*i]
set title "Interval no. ".i
plot "data" w l
pause 2
}
This looks like so:

Specific gnuplot by data grouping

I'm new in gnuplot and sorry that my problem formulation might be unprecise, but I don't know how to find the tools/commnds needed to solve my problem. The code for plotting I would like to integrate in my bash file.
I have a data set like:
285 1 50 7.35092
265 1 50 7.35092
259 1 50 7.35092
258 1 50 7.35092
264 1 50 7.35092
491 5 50 33.97
488 5 50 33.97
495 5 50 33.97
492 5 50 25.1649
495 5 50 33.0725
500 5 50 13.6176
507 5 50 32.2502
489 5 50 33.0725
494 5 50 33.97
491 5 50 33.97
746 10 50 34.6007
746 10 50 34.6007
767 10 50 30.858
745 10 50 34.8789
746 10 50 34.6007
747 10 50 34.6007
758 10 50 34.6007
772 10 50 34.60
I already grouped the data by entering a new line between blocks. I would like to calculate for each block the mean and standard deviation of the 4th column.
Then I would like to plot on the Y axes the mean with the confidence interval (standard deviation) and on the X axes the value from the second column.
Each data block has a unique number in the 2nd column.
Solution: so far I got the values for a point from the first block but while I try to plot I get an error:
#myBash code for plotting.sh
FILEIN=simulationR.txt
rm plotTestR.png
gnuplot << EOF
reset
set terminal png
set output 'plotTestR.png'
set ylabel 'reward'
set xlabel 'Nr of simualtion'
set title 'Simualtio duration'
set grid
stats "$FILEIN" using 4 every :::0::0 nooutput
mean1 = sprintf('%.3f', STATS_mean)
std1 = sprintf('%.3f', STATS_stddev)
stats "$FILEIN" using 2 every :::0::0 nooutput
x1 = sprintf('%.3f', STATS_max)
plot '-' w yerrorbars title std1
x1 mean1 std1
exit
EOF
and the error:
gnuplot> plot '-' w yerrorbars title std1
^
line 1: Bad data on line 1 of file -
Usually, gnuplot isn't made for such data processing tasks. That's best done with an external script, which does the processing and writes to stdout, which can then be feed directly to gnuplot like
plot '< python myscript.py simulationR.txt'
In your example, you can only have fixed data after the plot '-' part, no variable substitution is done here.
However, gnuplot version 5 introduces a new inline data structure, to which you can write your computed values (set print $data).
Note, that the following is a plain gnuplot script, if you want to wrap it in a bash script (which is not necessary, since you can pass variables to a gnuplot script via the command line), then you must escape the $ characters.
FILEIN="simulationR.txt"
system('rm -f plotTestR.png')
reset
set terminal pngcairo
set output 'plotTestR.png'
set ylabel 'reward'
set xlabel 'Nr of simulation'
set title 'Simulation duration'
set grid
set print $data
do for [i=0:2] {
stats FILEIN using 2:4 every :::i::i nooutput
print sprintf("%e %e %e", STATS_max_x, STATS_mean_y, STATS_stddev_y)
}
set autoscale xfix
set offsets 1,1,0,0
plot $data using 1:2:3 w yerrorbars
A further improvement could be to separate two blocks by two blank lines, in which case you can use
stats 'simulationR.txt' using 0 nooutput
to have the number of blocks in the variable STATS_blocks, and you can rewrite the loop as
do for [i=0:STATS_blocks-1] {
stats FILEIN using 2:4 index i nooutput
print sprintf("%e %e %e", STATS_max_x, STATS_mean_y, STATS_stddev_y)
}

How to get a radial(polar) plot using gnu plot?

I want a radial(polar) plot using gnuplot (i.e in circular co-ordinate system(r,theta).
Here I have used the values:
Theta Max-strain
0 3400
60 5300
120 4700
180 3800
240 4100
300 3100
360 3400
How to get such a plot using gnu-plot?
I tried to recreate the plot of your question and this is what I came up with:
unset border
set polar
set angles degrees #set gnuplot on degrees instead of radians
set style line 10 lt 1 lc 0 lw 0.3 #redefine a new line style for the grid
set grid polar 60 #set the grid to be displayed every 60 degrees
set grid ls 10
set xrange [-6000:6000] #make gnuplot to go until 6000
set yrange [-6000:6000]
set xtics axis #disply the xtics on the axis instead of on the border
set ytics axis
set xtics scale 0 #"remove" the tics so that only the y tics are displayed
set xtics ("" 1000, "" 2000, "" 3000, "" 4000, "" 5000, "" 6000) #set the xtics only go from 0 to 6000 with increment of1000 but do not display anything. This has to be done otherwise the grid will not be displayed correctly.
set ytics 0, 1000, 6000 #make the ytics go from the center (0) to 6000 with incrment of 1000
set size square
set key lmargin
set_label(x, text) = sprintf("set label '%s' at (6500*cos(%f)), (6500*sin(%f)) center", text, x, x) #this places a label on the outside
#here all labels are created
eval set_label(0, "0")
eval set_label(60, "60")
eval set_label(120, "120")
eval set_label(180, "180")
eval set_label(240, "240")
eval set_label(300, "300")
set style line 11 lt 1 lw 2 pt 2 ps 2 #set the line style for the plot
#and finally the plot
plot "-" u 1:2 t "Max strain" w lp ls 11
0 3400
60 5300
120 4700
180 3800
240 4100
300 3100
360 3400
e
As you can see, the major difference is that the angle 0 is not on top but on the right (which is mathematically correct). You can change this however by modifying the using deceleration in the plot and the set_label function.
As you can see in the script not everything is really crisp and shiny. If someone finds improvements please let me know!
One last bit of "advice": It is not always reasonable to try to reproduce a plot from some tool with gnuplot. Often the strength of gnuplot is to plot data in the most simple way to be easily reproducible. Maybe you can kick some lines out of that script above and still be happy with it.
Here is a manual http://t16web.lanl.gov/Kawano/gnuplot/polar-e.html
set polar
set angles degrees
and to get circles:
set grid polar
Here is a demo: http://gnuplot.sourceforge.net/demo/polar.html

Resources