Marking zero values with a red line in gnuplot - 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:

Related

Plotting with GNU Plot, title based on column name

I have a file composed of 3 columns, which format is: X Axis Value | Title ID | Y axis Value
I don´t know how to plot it using columns 1:3 and 2 for the title name. Here is an example:
X Axis Plot Y Axis
2000 plot1 1.2
2000 plot2 4.6
2000 plot3 5.7
3000 plot1 5.8
3000 plot2 7.5
3000 plot3 8.3
So here, we will have 3 plots which should have second column values on their names (1, 2 and 3); 2000 and 3000 would be the X axis values and the thrid column represents de Y value.
So, the "title-2" graph would be: (2000, 4.6) and (3000, 7.5)
If you are a UNIX user or the "grep" command is callable from gnuplot, you may consider the following approach.
set xrange [1000:4000]
set yrange [0:10]
plot for [i=1:3] \
sprintf("< grep plot%i test.dat",i) using 1:3 with linespoints title sprintf("plot%i", i)
The above plot command is a bit more complicated because of the use of "for loop" and "sprintf", but is equivalent to the following.
plot "< grep plot1 test.dat" using 1:3 with linespoints title "plot1", \
"< grep plot2 test.dat" using 1:3 with linespoints title "plot2", \
"< grep plot3 test.dat" using 1:3 with linespoints title "plot3"
The adapted "gnuplot only" version for your case might look like this.
fcol is the filter column number, myKey your keyword, and dcol the data column number. It's not clear to me whether you want 3 lines in 1 graph, or 3 lines in 3 graphs on 1 canvas (multiplot, like example below), or the graph in 1 file on disk or maybe distributed on 3 files on disk.
Code:
### split data by keyword for each plot
reset session
$Data <<EOD
X Axis Plot Y Axis
2000 plot1 1.2
2000 plot2 4.6
2000 plot3 5.7
3000 plot1 5.8
3000 plot2 7.5
3000 plot3 8.3
EOD
myFilter(fcol,myKey,dcol) = strcol(fcol) eq myKey ? column(dcol) : NaN
set datafile missing NaN
set key top left
set multiplot layout 3,1
do for [i=1:3] {
myKey = sprintf("plot%d",i)
set title myKey
plot $Data u 1:(myFilter(2,myKey,3)) w lp pt 7 lc i title myKey
}
unset multiplot
### end of code
Result:
Addition: (all lines in one plot)
If you have regular file pattern in your rows, e.g. 1,2,3,1,2,3,1,2,3,... or 1,1,1,2,2,2,3,3,3,... you possibly could also work with every, check help every.
However, this filtering with the ternary operator should work for all cases, including random 1,3,2,2,3,1,1,2,3,... sequences.
Code:
### split data by keyword
reset session
$Data <<EOD
X Axis Plot Y Axis
2000 plot1 1.2
2000 plot2 4.6
2000 plot3 5.7
3000 plot1 5.8
3000 plot2 7.5
3000 plot3 8.3
EOD
myFilter(fcol,myKey,dcol) = strcol(fcol) eq myKey ? column(dcol) : NaN
set datafile missing NaN
set key top left
myKey(i) = sprintf("plot%d",i)
set title "Plot 1,2,3"
plot for [i=1:3] $Data u 1:(myFilter(2,myKey(i),3)) w lp pt 7 lc i title myKey(i)
### end of code
Result:

Gnuplot: Find y value for given x value

I have a set of data points I plot with gnuplot. Know I calculate a value for x and want to find the corresponding y value within the data.
Does anybody know how to manage this with gnuplot?
I found kind of a solution here on StackOverflow
Basically you have to invert the function you use to calculate y (or x in the case of the link) and then, thanks to the sprintf function, you gate the corresponding value.
NOTE
Have a look also here if you did not find the solution at the first link!
Although this is a rather old question, the following solution for interpolation might still be of interest to others.
The code can be simplified depending on whether you are just interested in nearest datapoint or in the interpolated value or whether you want to plot the value as point and/or label.
Code:
### interpolate between datapoints
reset session
$Data <<EOD
0 0
0.30 0.20
0.60 0.40
0.80 0.80
1 1
EOD
$Data2 <<EOD
1 0
0.80 0.15
0.50 0.30
0.50 0.50
0.30 0.80
0 1
EOD
InterpolY(x,x0,x1,y0,y1) = (x-x0)*(x-x1)<0 || x1-x0==0 ? x1-x0==0 ? (y0+y1)/2 : (y1-y0)/(x1-x0)*(x-x0) +y0 : NaN
set key noautotitle
array Point[1] # dummy array for plotting a single datapoint
# x-value for interpolation is defined in xp
plot x1=y1=yp=(xp=0.7,NaN) $Data u (x0=x1,x1=$1):(y0=y1,y1=$2, yp==yp ? NaN : yp=InterpolY(xp,x0,x1,y0,y1),y1) w lp pt 7, \
Point u (xp):(yp) w p pt 7 lc "red", \
Point u (xp):(yp):(sprintf("(%.2g|%.2g)",xp,yp)) w labels right offset -1,0 lc "red", \
x1=y1=yp=(xp=0.5,NaN) $Data2 u (x0=x1,x1=$1):(y0=y1,y1=$2, yp==yp ? NaN : yp=InterpolY(xp,x0,x1,y0,y1),y1) w lp pt 7, \
Point u (xp):(yp) w p pt 7 lc "green", \
Point u (xp):(yp):(sprintf("(%.2g|%.2g)",xp,yp)) w labels right offset -1,0 lc "green", \
### end of code
Result: (interpolated values at x=0.7 and x=0.5)

Gnuplot 1d plot

I have a text file of the position of particles along the x axis which changes after every collision. Example data.
0 7.5 10 30 30 40
0 9.375 10 32.5 40 40
0 10 10 33.3333 36.6667 40
0 10.25 10.75 34 34 40
0 11.0938 13.2812 28.75 40 40
I am currently trying to plot the data using gnu plot. What I want it to do is have these points along the x axis but instead of plotting the whole file at once I would like gnu plot to plot one line at a time . Furthermore, so the data is identifiable I am trying to plot the points as large markers instead of points. I am struggling to do this and any help would be appreciated.
Firstly, convert the rows to columns using AWK
awk '{for(i=1;i<=NF;i++)a[NR,i]=$i}END{for(i=1;i<=NF;i++){for(j=1;j<=NR;j++)printf a[j,i]"\t";printf "\n"}}' original.dat > particle.dat
#suppose that your input data is original.dat and the output data is particle.dat
The converted data are:
0 0 0 0 0
7.5 9.375 10 10.25 11.0938
10 10 10 10.75 13.2812
30 32.5 33.3333 34 28.75
30 40 36.6667 34 40
40 40 40 40 40
Then, plot your data with the following code in gnuplot:
set border 1
#`set border 1` means only showing the bottom border of the plot. see `help border` for more information
set xtics nomirror
#only show the bottom tics on the x axis and suppress the upper tics of the x axis
unset ytics
#suppress the tics on the y axis
set key outside
#set the legend out side the plot
plot "particle.dat" using 1:(1) with points pointtype 7 pointsize 3 title "particle 1", "" u 2:(2) w p pt 7 ps 3 t "particle 2", "" u 3:(3) w p pt 7 ps 3 t "particle 3", "" u 4:(4) w p pt 7 ps 3 t "particle 4", "" u 5:(5) w p pt 7 ps 3 t "particle 5"
#`using 1:(1)` means use the first column as X and a constant number of 1 as Y. see `help using` for more details
#`u` is short for `using`and `w p pt 7 ps 3` is short for `with points pointtype 7 pointsize 3.
The output of the plot is
I don't think that you have to transpose the data using awk, as each row already contains the data of a single particle.
So, based on the code from DragonHu, I have this:
To generate this plot, I also added lines to connect the points. Also, I used the special column number 0 which just gives the line number in the datafile, starting at 0.
Another trick: Using backslash \, you can split a command to multiple lines. Here is the plot command I used:
plot "particle.dat" using 1:0 with points linetype 1 pointtype 7 pointsize 3 title "particle 1",\
"" u 1:0 notitle w l lt 1,\
"" u 2:0 w p lt 2 pt 7 ps 3 t "particle 2", \
"" u 2:0 notitle w l lt 2,\
"" u 3:0 w p lt 3 pt 7 ps 3 t "particle 3", \
"" u 3:0 notitle w l lt 3,\
"" u 4:0 w p lt 4 pt 7 ps 3 t "particle 4", \
"" u 4:0 notitle w l lt 4,\
"" u 5:0 w p lt 5 pt 7 ps 3 t "particle 5",\
"" u 5:0 notitle w l lt 5
Still, this is not yet the answer, as the question is to plot one set of points at a time. This can be achieved with the following code. It generates five single plots which I dumped into an animated gif figure:
set key center
set yrange[0:1]
set xrange[0:40]
set terminal gif size 600, 200 animate delay 100
set output "animated.gif"
do for [n=0:4] {
set title sprintf("Lineno. %d", n)
plot "particle.dat" every ::n::n using 1:(0) with points pointtype 7 pointsize 3 title "particle 1",\
"" every ::n::n u 2:(0) w p pt 7 ps 3 t "particle 2", \
"" every ::n::n u 3:(0) w p pt 7 ps 3 t "particle 3", \
"" every ::n::n u 4:(0) w p pt 7 ps 3 t "particle 4", \
"" every ::n::n u 5:(0) w p pt 7 ps 3 t "particle 5",\
}
unset output
If single images should be created, it is possible via
set terminal ongcairo
do for [n=0:4] {
set title sprintf("Lineno. %d", n)
set output sprintf("PictureNumber_%d",n)
plot ...
unset output
}

gnuplot: how to label points in multiplot

I want to label points on the plot using 'with labels' command but I get 'not enough columns for this style' error. My datafile looks like this:
method ∆G
A 0
B 15.01
C -1.4
D 12.2
E -3.9
method ∆H
A 0
B 8.4
C -2.58
D 3.6
E -2.12
method ∆SCF
A 0
B 11.66
C -0.96
D 6.28
E -1.3
I use this command to create a plot:
plot 'file.dat' using 2:xticlabel(1) index 0 pointtype 18 wth labels,''using 2 index 1 pointtype 18 with labels,''using 2 index 2 pointtype 18 with labels
I know that 'with labels' command requires 3 arguments, so the problem is probably lack of the third argument, but I've checked many combination and there was always some error. What am I doing wrong?
For your "missing" 3rd column you can use the pseudocolumn 0 (check help pseudocolumns).
If you want to address blocks via index you need to have two empty lines as separator. If you change your datafile format a bit it will make your script simpler.
The labels will have an offset depending on the sign. You can achieve this with the ternary operator, e.g. ($2<0?-1:1), (check help ternary). You could add another fixed offset via offset (check help label).
Data: SO24044166.dat
method ∆G
A 0
B 15.01
C -1.4
D 12.2
E -3.9
method ∆H
A 0
B 8.4
C -2.58
D 3.6
E -2.12
method ∆SCF
A 0
B 11.66
C -0.96
D 6.28
E -1.3
Script: (works with gnuplot 4.6.0, March 2012)
### use of pseudocolumn as x-value
reset
FILE = "SO24044166.dat"
set key title "methods" noautotitle
set style fill solid 0.3
set grid y
set yrange[-6:18]
set boxwidth 0.23
plot for [i=0:2] FILE u ($0+i/3.5):2 index i w boxes ti columnhead, \
for [i=0:2] '' u ($0+i/3.5):($2+($2<0?-1:1)):2 index i every ::1 w labels offset 0,0 notitle, \
'' u ($0+1/3.5):(NaN):xtic(1) index 0 every ::1
### end of script
Result: (created with gnuplot 4.6.0)

Gnuplot: plotting points with variable point types

I have x,y values for points in the first 2 colums and a number that indicates the point type (symbol) in the 3. column, in one data file. How do I plot data points with different symbols?
Unfortunately, there isn't a way (AFAIK) to automatically set the point of the plot from a column value using vanilla GNUPLOT.
However, there is a way to get around that by setting a linestyle for each data series, and then plotting the values based on that defined style:
set style line 1 lc rgb 'red' pt 7 #Circle
set style line 2 lc rgb 'blue' pt 5 #Square
Remember that the number after pt is the point-type.
Then, all you have to do is plot (assuming that the data in "data.txt" is ordered ColX ColY Col3):
plot "data.txt" using 1:2 title 'Y Axis' with points ls 1, \
"data.txt" using 1:3 title 'Y Axis' with points ls 2
Try it here using this data (in the section titled "Data" - also note that column 3 "Symbol" is noted used, it's mainly there for illustrative purposes):
# This file is called force.dat
# Force-Deflection data for a beam and a bar
# Deflection Col-Force Symbol
0.000 0 5
0.001 104 5
0.002 202 7
0.003 298 7
And in the Plot Script Heading:
set key inside bottom right
set xlabel 'Deflection (m)'
set ylabel 'Force (kN)'
set title 'Some Data'
set style line 1 lc rgb 'red' pt 7
set style line 2 lc rgb 'blue' pt 5
plot "data.txt" using 1:2 title 'Col-Force' with points ls 1, \
"data.txt" using 1:3 title 'Beam-Force' with points ls 2
The one caveat is of course that you have have to reconfigure your data input source.
REFERENCES:
http://www.gnuplotting.org/plotting-single-points/
http://www.gnuplotting.org/plotting-data/
Here is a possible solution (which is a simple extrapolation from gnuplot conditional plotting with if), that works as long as you don't have tens of different symbols to handle.
Suppose I want to plot 2D points in a coordinate system. I have only two symbols, that I arbitrarily represented with a 0 and a 1 in the last column of my data file :
0 -0.29450470209121704 1.2279523611068726 1
1 -0.4006965458393097 1.0025811195373535 0
2 -0.7109975814819336 0.9022682905197144 1
3 -0.8540692329406738 1.0190201997756958 1
4 -0.5559651851654053 0.7677079439163208 0
5 -1.1831613779067993 1.5692367553710938 0
6 -0.24254602193832397 0.8055955171585083 0
7 -0.3412654995918274 0.6301406025886536 0
8 -0.25005266070365906 0.7788659334182739 1
9 -0.16853423416614532 0.09659398347139359 1
10 0.169997438788414 0.3473801910877228 0
11 -0.5252010226249695 -0.1398928463459015 0
12 -0.17566296458244324 0.09505800902843475 1
To achieve what I want, I just plot my file using conditionals. Using an undefined value like 1/0 results in no plotting of the given point:
# Set styles
REG_PTS = 'pointtype 7 pointsize 1.5 linecolor rgb "purple"'
NET_PTS = 'pointtype 4 pointsize 1.5 linecolor rgb "blue"'
set grid
# Plot each category with its own style
plot "data_file" u 2:($4 == 0 ? $3 : 1/0) title "regular" #REG_PTS, \
"data_file" u 2:($4 == 1 ? $3 : 1/0) title "network" #NET_PTS
Here is the result :
Hope this helps
Variable pointype (pt variable) was introduced (I guess) not until gnuplot 5.2.0 (Sept 2017) (check help points).
Just in retrospective, another (awkward) solution would be the following for those who are still using such early versions.
Data:
1 1.0 4 # empty square
2 2.0 5 # filled square
3 3.0 6 # empty circle
4 4.0 7 # filled circle
5 5.0 8 # empty triangle up
6 6.0 9 # filled triangle down
7 7.0 15 # filled pentagon (cross in gnuplot 4.6 to 5.0)
Script: (works from gnuplot>=4.6.0, March 2012; but not necessary since 5.2.0)
### variable pointtype for gnuplot>=4.6
reset
FILE = 'SO23707979.dat'
set key noautotitle
set offsets 1,1,1,1
set pointsize 4
stats FILE u 0 nooutput
N = STATS_records # get the number of rows
p0=x1=y1=NaN
plot for [n=0:N-1 ] FILE u (x0=x1, x1=$1, x0):(y0=y1, y1=$2, y0):(p0=$3) \
every ::n::n w p pt p0 lc rgb "red", \
FILE u 1:2 every ::N-1::N-1 w p pt p0 lc rgb "red"
### end of script
Result:

Resources