Combining yerrorbars and variable point size - gnuplot

I'm trying to plot the following data file
#x y s err
1 1 0.1 0.2
2 2 0.2 0.2
3 3 0.3 0.2
4 4 0.4 0.2
5 5 0.5 0.2
6 6 0.6 0.2
7 7 0.7 0.2
8 8 0.8 0.2
9 9 0.9 0.2
10 10 1.0 0.2
where the points have a variable size given by column 3 and the errors are given in column 4. I can get
plot "test" u 1:2:3 pt 7 ps variable
plot "test" u 1:2:4 w yerrorbars pt 7
to work independently, giving me this:
But when I try to combine them
plot "test" u 1:2:4:3 w yerrorbars pt 7 ps variable
I get something very strange:
yerrorbars seems to be using column 4 as the y column and column 3 as the yerror column. Even stranger, I get the same output if I try u 1:2:3:4. Is there something wrong with how I'm doing this? I can manually draw the errorbars as vectors, but I'd prefer to use the built-in errorbars style if possible.

gnuplot> help yerrorbars
The `yerrorbars` (or `errorbars`) style is only relevant to 2D data plots.
`yerrorbars` is like `points`, except that a vertical error bar is also drawn.
At each point (x,y), a line is drawn from (x,y-ydelta) to (x,y+ydelta) or
from (x,ylow) to (x,yhigh), depending on how many data columns are provided.
The appearance of the tic mark at the ends of the bar is controlled by
`set errorbars`.
2 columns: [implicit x] y ydelta
3 columns: x y ydelta
4 columns: x y ylow yhigh
An additional input column (4th or 5th) may be used to provide information
such as variable point color.
So in order to provide more than 3 columns and still use a single value for the ydelta, you should be able to do
plot "test" u 1:2:($2-$4):($2+$4):3 w yerrorbars pt 7 ps variable
However, as you point out this doesn't actually work as documented.
Work-around
An alternative is to make two passes; first plot the errorbar lines and suppress the points, second plot the point with the desired properties :
unset key
plot "test" u 1:2:3 with yerrorbars pt 0, \
"" u 1:2:4 with points pt 7 ps variable

Related

Gnuplot pull function range from a file for each row

I am trying to display a function which is a linear function f(x)=a*x+b with different coefficients in each range. My file (output.txt) looks like this but without the header:
a b range
-0.0645991 0.439102 0 0.25
-0.230142 0.480488 0.25 0.5
-0.438559 0.584697 0.5 0.75
-0.66962 0.757993 0.75 1
-0.898603 0.986975 1 1.25
-1.09846 1.2368 1.25 1.5
-1.24232 1.45259 1.5 1.75
-1.30601 1.56404 1.75 2
I have tried these lines but none of them worked:
plot "output.txt" using 1:2 with lines, set xrange using 3:4
plot "output.txt" [($3):($4)] ($1)*x+($2)
plot "output.txt" $3<=x<=$4 ? ($1)*x+($2) : 0
It's my first time using Gnuplot and I couldn't find any example of pulling range from a file.
Welcome to StackOverflow! You can simply use the plotting style with vectors.
Check help vectors.
The plotting command looks complicated but it is straightforward.
The four values you need are: x, y, delta x, and delta y, i.e.
in your example
x: 3rd column
y: f(x,a,b) where x is 3rd column and a and b are from 1st and 2nd columns, respectively.
dx: 4th column less 3rd column
dy: f(x,a,b) where x is from 4th column less f(x,a,b) where x is from 3rd column and a,b as above.
You can skip the arrow heads if you specify nohead in the plot command. Check help arrow.
Code:
### plotting style with vectors
reset session
$Data <<EOD
a b range
-0.0645991 0.439102 0 0.25
-0.230142 0.480488 0.25 0.5
-0.438559 0.584697 0.5 0.75
-0.66962 0.757993 0.75 1
-0.898603 0.986975 1 1.25
-1.09846 1.2368 1.25 1.5
-1.24232 1.45259 1.5 1.75
-1.30601 1.56404 1.75 2
EOD
f(x,a,b) = a*x + b
plot $Data u 3:(f($3,$1,$2)):($4-$3):(f($4,$1,$2)-f($3,$1,$2)) w vectors lc "red" head title "my function"
### end of code
Result:

gnuplot's 'steps' style does not accept variable color

I'm using Gnuplot Version 5.2 patchlevel 6 on Debian 10. The following program
$d << EOD
1 0.5 0.1
2 0.75 0.2
3 0.99 0.5
4 1.25 1.1
EOD
plot $d using 1:2:3 w lines lc palette z lw 2
produces an expected output:
But if I change the last line to
plot $d using 1:2:3 w steps lc palette z lw 2
I receive an error message:
line 7: Too many using specs for this style
According to paragraphs II Plotting Styles, Steps in Gnuplot User Manual
The input column requires are the same as for plot styles lines and points.
and in paragraph II Plotting Styles, Lines stated that:
The basic form requires 1, 2, or 3 columns of input data. Additional input columns may be used to provide information such as variable line color
What am I doing wrong?
If you are drawing with steps, the question probably is: which color should the vertical lines have?
Quickly checking the documentation I couldn't find a hint whether variable line color together with steps explicitely works or explicitely doesn't work.
In any case, you can workaround with the following code:
Code:
### plotting with steps and variable line color
reset session
$Data <<EOD
1 0.5 0.1
2 0.75 0.2
3 0.99 0.5
4 1.25 1.1
EOD
set xrange [0:5]
set yrange [0:1.5]
plot x1=y1=NaN $Data u (x0=x1,x1=$1,x0):(y0=y1,y1=$2,y0):(x1-x0):(0):3 w vectors lw 2 lc palette nohead notitle, \
x1=y1=NaN $Data u (x0=x1,x1=$1,x1):(y0=y1,y1=$2,y0):(0):(y1-y0):3 w vectors lw 2 lc palette nohead notitle
### end of code
Result:
Addition: (vertical lines with variable colors)
Maybe you noticed that with your 4 datapoints there are only 3 colors. This is obvious, because if you have 4 data points you will only have 3 connecting lines, hence 3 colors.
A variation would be the following:
Draw your 4 points with the color according to the value column 3 and the same color for the horizontal lines.
However, for the vertical lines you split the lines into as many levels you want (here: myLevels = 20) using the color according to the palette.
Code:
### plotting with steps and variable line color (vertical lines with variable color)
reset session
$Data <<EOD
1 0.5 0.1
2 0.75 0.2
3 0.99 0.5
4 1.25 1.1
EOD
set xrange [0:5]
set yrange [0:1.5]
myLevels = 20
plot x1=y1=c1=NaN $Data u (x0=x1,x1=$1,x0):(y0=y1,y1=$2,y0):(x1-x0):(0):(c0=c1,c1=$3,c0) w vectors lw 2 lc palette nohead notitle, \
for [i=0:myLevels-1] x1=y1=NaN $Data u (x0=x1,x1=$1,x1):(y0=y1,y1=$2,y0+(y1-y0)*i/myLevels):(0):((y1-y0)/myLevels):(c0=c1,c1=$3,c0+(c1-c0)*i/myLevels) w vectors lw 2 lc palette nohead notitle, \
$Data u 1:2:3 w p pt 7 ps 2 lc palette notitle
### end of code
Result:

How to plot points specified by ID column only with linespoints and multiple plots using gnuplot?

Say I have two files, each has 3 columns
file1:
ID X Y
10 0.1 some data as X
20 0.2
30 0.3
... ...
120 0.5
file2:
ID X Y
15 0.1 some data as X
30 0.2
45 0.3
60 0.4
... ...
120 0.6
I am doing
plot \
"file1" using 2:3 w linespoints lt 1 dt 1 lw 1 lc 1 title "file1",\
"file2" using 2:3 w linespoints lt 1 dt 1 lw 1 lc 2 title "file2"
which shows every point on the file.
If I only want points which its Row ID(first column) is 30, 60 ,90 ,120
How should I do? Thank you.
*In the actually case, I need to plot 12 file in one plot and each of them have 10000 rows but I only want to show 6 points.
You can filter your data with the ternary operator. Check help ternary.
For the filename and the filter I would define a function such that you have it compact in your plot command.
What myFilter(dcol,fcol) does is returning the value of the data column dcol if the filter column fcol is equal to one of the given values.
myFilename(n) creates the filename as a function of a number.
I don't have test files but the following should plot the 12 files names "file1.dat", ..., "file12.dat".
I hope you can adapt it to your exact needs.
Code:
### filter data with ternary operator
reset session
myFilename(n) = sprintf("file%d.dat",n)
myFilter(dcol,fcol) = column(fcol)==30 || column(fcol)==60 || \
column(fcol)==90 || column(fcol)==120 ? column(dcol) : NaN
set datafile missing NaN
plot for [i=1:12] myFileName(i) u 2:(myFilter(3,1)) w lp ti myFilename(i)
### end of code

gnuplot - how to plot invisible points so that the plot is only used to mark x-axis

I have the following data in data file test1.txt:
A 36 1
A 35 1
B 48 2
B 37 2
B 15 2
C 36 3
C 25 3
and test2.txt
A 16 1
A 25 1
B 38 2
B 45 2
C 36 3
the plotting is done as:
dat1="test1.txt"
dat2="test2.txt"
plot dat1 u ($3-0.2):2 w p t 'title 1', \
dat2 u ($3+0.2):2 w p t 'title 2', \
dat1 using 3:(0):xticlabels(1):x2ticlabels(1) notitle, \
dat2 using 3:(0):xticlabels(1):x2ticlabels(1) notitle
The whole point is to have the labels from the first column on the x axis. The issue is that the last two parts of plot
dat1 using 3:(0):xticlabels(1):x2ticlabels(1) notitle, \
dat2 using 3:(0):xticlabels(1):x2ticlabels(1) notitle
produce points at y=0. And because I cannot (or I do not know how to) use
plot dat1 u ($3-0.2):2:xticlabels(1) w p t 'title 1'
(since it plots the label at x coordinate $3-0.2 and not at $3, which i require), I am forced to do two more dummy plots, but they produce points and I do not know how to effectively avoid this other than shifting the outside of the range of the plot by e.g. dat1 using 3:(0):xticlabels(-1):x2ticlabels(-1) in the case of plotting only positive values. Is there any good way of solving this?
I don't really understand what you are trying to do with your data, however if you want to make the points over the x axis invisible you can set the line color to full transparency for the last two plots:
dat1 using 3:(0):xticlabels(1):x2ticlabels(1) linecolor "#FFFF0000" notitle, \
dat2 using 3:(0):xticlabels(1):x2ticlabels(1) linecolor "#FFFF0000" notitle
In recent versions of Gnuplot (link) it is possible to add transparency, in this particular case you want to set full transparency to the line color so that the points are invisible. The color format and transparency can be set using the hexadecimal notation #AARRGGBB where AA (alpha) controls how transparent the color is, for full transparency you want FF which is equivalent to 255, notice how my line color is RED but because is completely transparent we don't see it.
Plot with Full Transparency
My understanding of your question is the following: You have some data which you want to shift in x by +/-0.2 but the corresponding tic shouldn't be shifted.
You've been almost there. Of course, there are points at y=0 because you tell gnuplot to do so.
What you mean with "invisible" could of course be also achieved by fully transparent points, but the easier way is probably to "plot" the points at NaN, i.e. nowhere.
Code:
### plotting data with offset and tic without offset
reset session
set colorsequence classic
$Data1 <<EOD
A 36 1
A 35 1
B 48 2
B 37 2
B 15 2
C 36 3
C 25 3
EOD
$Data2 <<EOD
A 16 1
A 25 1
B 38 2
B 45 2
C 36 3
EOD
set offsets 0.5,0.5,0.5,0.5
set link x2
set x2tics
plot $Data1 u ($3-0.2):2 w p pt 7 t 'title 1', \
$Data2 u ($3+0.2):2 w p pt 7 t 'title 2', \
$Data1 using 3:(NaN):xtic(1):x2tic(1) notitle, \
$Data2 using 3:(NaN):xtic(1):x2tic(1) notitle
### end of code
Result:

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