gnuplot: Connect points even when missing/invalid are inbetween - gnuplot

I have a data file with interleaving data rows from different devices.
Now, I'd like to plot data from one devices with linepoints and use this to filter only the device of interest:
plot 'datafile' using (<someCondition> ? $1 : 1/0):2
Now, gnuplot does not connect the points because there is always some invalid data inbetween.
Is it possible to make gnuplot to connect my points?
By the way: This is a Windows machine, so an external sed/awk/whatever command is no option.

Since gnuplot version 5.0.6 you can use set datafile missing NaN to have invalid points treated as missing ones, and drawing with lines or with linespoints simply ignores those points and connects the others
$data <<EOD
12
27
0
23
42
EOD
set multiplot layout 1,2
set title '0.0 invalid'
plot $data using 0:($1 == 0.0 ? 1/0 : $1) with linespoints pt 7 notitle
set title '0.0 invalid but treated as missing'
set datafile missing NaN
replot
unset multiplot
Output with 5.0.6:

Related

Gnuplot: Violin plot with data from file

I created a script to plot the columns of a dataset using violin plots to show the distribution of the data points starting from the Gnuplot Demo Scripts. However, I can't solve the following error:
"violinplot.gnu", line 27: all points y value undefined!
Does anyone have any idea?
The script:
reset
set terminal pdfcairo size 20,14 enhanced font 'Times,28'
set output 'violinplot.0.pdf'
set datafile separator ','
set table $kdensity1
plot 'profile.csv' using 2:(1) smooth kdensity bandwidth 10. with filledcurves above y lt 9 title 'B'
unset table
unset key
print $kdensity1
set border 2
#unset margins
#unset xtics
set ytics nomirror rangelimited
set title "Distribution of times in milliseconds"
set boxwidth 0.075
set style fill solid bo -1
set errorbars lt black lw 5
set xrange [-6:6]
plot $kdensity1 using (1 + $2/1.):1 with filledcurve x=1 lt 10, \
$kdensity1 using (1 - $2/1.):1 with filledcurve x=1 lt 10
The dataset is in a CSV format as follows (and each column contains time in milliseconds):
1,1814,604,840,1306,13623
2,2195,68,908,1380,14416
3,1173,70,887,512,14301
4,1286,112,982,1541,9549
5,630,97,869,1321,5725
6,1227,689,917,393,4700
7,3402,357,951,500,5431
8,3429,120,969,1661,6281
...
Gnuplot Version 5.2 patchlevel 2
The reason for your error is simple but "nasty" and hidden.
Your input data is comma separated. However, if you plot to a table via set table $kdensity the default column separator is whitespace. That's why gnuplot doesn't find any data in column 2.
I guess since gnuplot 5.2.2. you could set set table $kdensity separator comma. But in order to get a comma as separator you have to use the "plotting style" with table (e.g. plot FILE u 1:2 w table). However, with table and smooth ... do not work together. Either you use with table and you will get the comma but not "smoothed" or you "smooth" and you will not get the comma.
Two possible solutions:
after plotting to the smoothed table set your separator to whitespace (see example below).
or alternatively,
change your input data to whitespace separated.
If you want plot the original (comma separated) data as well, then you have two different column separators. Then you have to apply another workaround.
Script: (works with gnuplot>=5.2.2)
### violin plot with comma separated input data
reset session
# create some random test data (comma separated)
set table $Data separator comma
set samples 100
n = 0
plot for [i=1:3] '+' u (n=n+1):(invnorm(rand(0))*i*25 +i*200) w table
unset table
set datafile separator ','
set table $kdensity
set samples 1000
plot $Data using 2:(1) smooth kdensity bandwidth 10.
unset table
set datafile separator whitespace
set key noautotitle
set style fill solid 0.7
plot $kdensity u (1 + $2/1.):1 w filledcurves x=1 lt 10, \
'' u (1 - $2/1.):1 w filledcurves x=1 lt 10
### end of script
Result:

Gnuplot: draw error bars of data points outside plotting range

If I set a specific yrange and plot in a pdf terminal with this plot command:
plot "data.dat" u 1:4:5:6 w yerrorbars pt 6 ps 0.5 t "R_t"
errorbars that belong to data points outside the yrange, but end inside the yrange are not shown.
How do I force gnuplot to draw those. I already tried "set clip one/two"
The only workaround I found is to plot the data 3 times, once for the central point and once for each side of the error bar.
Use "-" as symbol for the errorbars and use their own "errorbars" to draw a line to the central point.
You could use multiplot to achieve this.
Set your plot to have zero margins, so the axes are on the border of the canvas, and switch of all tics and borders for the first plot.
Switch on the axes, tics etc. again, and do an empty plot that you set at the correct position using set size and set origin. You'll have to do some math to calculate the exact position.
#MaVo159, you can reduce it to plotting only twice by using with yerrorbars and with vectors (check help vectors). You need to set the proper arrow style, check help arrowstyle.
However, this works only for gnuplot>=5.2.3, for earlier versions there seems to be a bug which plots the arrowhead at the wrong side for some of the vectors extending the graph.
You nevertheless have to plot once with yerrorbars in order to get the proper legend.
Script: (works for gnuplot>=5.2.3, May 2018)
### plot errorbars from points outside the range
reset
$Data <<EOD
1 9 5.11 8.32
2 8 6.20 9.22
3 6 5.31 6.31
4 5 4.41 5.51
5 4 3.31 4.71
6 2.9 2.81 3.71
7 2 1.11 3.41
EOD
set yrange[3:7]
set offsets 1,1,0,0
set style arrow 1 heads size 0.05,90 lw 2 lc 1
set multiplot layout 2,1
plot $Data u 1:2:3:4 w yerrorbars pt 6 ps 2 lw 2
plot $Data u 1:2:3:4 w yerrorbars pt 6 ps 2 lw 2, \
'' u 1:3:(0):($4-$3) w vec as 1 notitle
unset multiplot
### end of script
Result:
You could modify your data file: Because the central value of the data point is outside the plot range you could set it equal to the errorbar's end point that would be still visible in your plot.
Example:
plot range: set yrange[-2:2]
data point: 1, -3, -1, -4 (x, y, ylow, yhigh)
set data point to: 1, -1, -1, -4
Attention: Since you have to edit your data file you should
Make a copy of the original data file
Be very careful when editing the file
Keep in mind, that when changing the plot range such that the central
value of the data point becomes visible you have to use the original data point. Otherwise you will see the correct error bar but there will be no central value plotted. (this is equivalent to setting 'point type' to 0)

GNUplot doesn't print lines

I'm having this script to plot some data in Gnuplot. Unfortunately, my plot doesn't print the lines, only the dots.
What have I done wrong?
#!/usr/bin/gnuplot
reset
set terminal png
set output 'picture.png'
set xlabel "n"
set ylabel "time (s)"
set yrange [0:2]
set title "title"
set key reverse Left outside
set grid
set style data linespoints
plot "bla.txt" using 1:2 title "bla" with linespoints ls 1
Most probably, your data file contains empty lines between successive data entries.
A data file with
1 2
2 4
5 6
shows only three points when plotted with
plot 'data.txt' using 1:2 with linespoints
whereas a data file
1 2
3 4
5 6
also shows connecting lines.
That is simply how gnuplot handles its data files.

How do I set axis label with column header in gnuplot?

My question is very simple. Suppose I have a datafile with column headers, like as follows
first second
1 1
2 1
3 6
4 9
In gnuplot how do i make it so that the datafile is plotted using the column header as axis label? e.g. by calling
plot datafile using 1:2
i get the xaxis labeled first and the yaxis labeled second?
edit: I do know that I can use the column header as a key entry via set key auto title column head, however that's not quite what I'm looking for.
To elaborate the suggestion of #andyras, here is how you can do it:
datafile = 'filename.txt'
firstrow = system('head -1 '.datafile)
set xlabel word(firstrow, 1)
set ylabel word(firstrow, 2)
plot datafile using 1:2
You must plot with the explicit using statement, otherwise gnuplot will complain about bad data on line 1.
I don't think this feature is built in to gnuplot; you would probably have to use an awk-like utility to pull those labels out of a datafile.
You could try submitting a feature request on gnuplot's sourceforge site, and get feedback from the developers there.
Another question where people believe it can't be done with gnuplot. Here is a simple gnuplot-only solution without external tools, hence platform-independent.
Data: SO16089301.dat
first second
1 1
2 1
3 6
4 9
Script: (works with gnuplot 4.6.0, March 2012)
### extracting axes labels from datafile
reset
FILE = 'SO16089301.dat'
stats FILE u (myX=strcol(1), myY=strcol(2)) every ::0::0 nooutput
set xlabel myX
set ylabel myY
plot FILE u 1:2 w lp pt 7 lc rgb "red"
### end of script
Result:
I think it is supported. You are just supposed to be able to use "":
plot 'file' using "first":"second"
Although, if you want to do math in your using specification, you'll need the column("") function, too
plot 'file' using "first":(column("second")-(column("thrid"))
(Using only quoted header names with the math didn't work for me, anyway.)

How to plot a point on a function in gnuplot

I need to plot a point on a graph of a function. I've seen gnuplot> plot “< echo ‘x y’” as an example, however, that only works on the terminal and I need it to be on a .gp file. I've also seen doing set parametric plot 4,3 but then I can't plot the point over the graph of the function.
Is there a way to do this?
Try something like:
set terminal postscript enhanced color
set output 'plot.eps'
set xr[-10:10]
set yr[-2:2]
plot sin(x), \
"<echo '3.141592 0'" pt 7 ps 2 notitle
The comma allows you to plot multiple things in the same plot. This way you have to specify the range and the point position manually, but it works for me in a plot script in gnuplot 4.6.
another option is to use 'inline data'
plot sin(x) w lines, '-' w p pt 7 ps 5
3.14 0
e

Resources