Gnuplot: plotting points with variable point types - gnuplot

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:

Related

gnuplot: how to set the different fill and border colors for `with points`?

I would like to achieve a similar effect in gnuplot.
Here is what I tried:
unset key
set style line 11 lc rgb '#808080' lt 1
set border 3 ls 11
set tics nomirror
set grid
set style line 1 lc rgb '#808080' pt 9 ps 3
set style line 2 lc rgb '#808080' pt 20 ps 3
set style line 3 lc rgb '#BD3828' pt 7 ps 3
set yrange [4:9]
$data << EOD
5 5.1
5.3 6.8
6 6
EOD
$data2 << EOD
5 5
7 7
8 6
EOD
$data3 << EOD
5.5 7
6 6
7 7.1
EOD
plot $data u 1:2 w points ls 1, $data2 u 1:2 w points ls 2, \
$data3 u 1:2 w points ls 3
As we can see, points can be overlapped. Then how can we darken the overlap areas?
A possible solution is to set transparency (e.g., lc rgb '#80808080'), but it will also make both border and filling transparent. So how to set the different fill and border colors for with points?
Another solution is to use set object, but we need to do more work to read data from files.
I think the closest you could come to what you describe is to draw the points in two passes.
First pass: draw using a point type that produces only the outlines (point types N = 4 6 8 10 12 ...).
Second pass: draw using the corresponding point type N+1 that produces only the interior, using the same color but adding an alpha channel value to make it partially transparent.
set print $RAND1
do for [i = 1:50] { print rand(0), rand(0) }
unset print
set print $RAND2
do for [i = 1:50] { print rand(0), rand(0) }
unset print
set pointsize 4
plot $RAND1 with points pt 8 lc rgb "#00b8860b", \
'' with points pt 9 lc rgb "#AAb8860b", \
$RAND2 with points pt 6 lc rgb "#00c04000", \
'' with points pt 7 lc rgb "#AAc04000"

Combining yerrorbars and variable point size

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

gnuplot: how to draw a set of triangles from a file?

In gnuplot, we can set object polygon to draw a polygon, including triangles, given its coordinates.
But how to do draw a set of triangles whose coordinates are stored in a file where each line is in the format <x1> <y1> <x2> <y2> <x3> <y3>?
As for rectrangles/circles, this task can be done using plot and with boxxy/with circles options, but there is no with triangles option in gnuplot.
A possible solution is to use with vectors by drawing each edge, but it is a bit complicated and this method does not support color filling.
I cannot think of a way to do this in one step; the data format does not match any of gnuplot's plotting styles.
One approach is to transform the data via a temporary file. Here is an example that works in version 5.2 and newer. If you are using a newer gnuplot then you could substitute with polygons for with filledcurves closed.
$DATA << EOD
1 1 2 2 3 1
11 11 14 14 17 11
21 21 22 22 23 21
15 5 16 6 17 5
6 6 7 7 8 6
EOD
set table "temp.dat"
plot $DATA using (sprintf("%g %g\n %g %g\n %g %g\n \n",$1,$2,$3,$4,$5,$6)) with table
unset table
unset key
set style fill solid noborder
plot "temp.dat" using 1:2 with filledcurves closed fillcolor "forest-green"
Note: I was originally going to show use of a temporary datablock rather than an intermediate temporary file, but it this doesn't work because the formatted output from with table does not translate the newline characters \n into empty datablock lines.
Edit (show variable color)
The extra data field containing a RGB color must be present in every input line of the reformatted data, but only the value from the first vertex of each polygon is used. The sprintf format in this example has been modified to reproduce the color (NB: hexadecimal integer value) from the original data file accordingly, with zeros for the dummy values in the remaining polygon vertices.
$DATA << EOD
1 1 2 2 3 1 0x00ffff
11 11 14 14 17 11 0x191970
21 21 22 22 23 21 0x2e8b57
15 5 16 6 17 5 0xffc020
6 6 7 7 8 6 0x8b000
EOD
set table "temp.dat"
plot $DATA using (sprintf("%g %g 0x%x\n %g %g 0\n %g %g 0\n \n",$1,$2,int($7),$3,$4,$5,$6)) with table
unset table
unset key
set style fill solid noborder
plot "temp.dat" using 1:2:3 with filledcurves closed fillcolor rgb variable
My suggestion would have been the same as #Ethan's. Therefore, here is an alternative approach using set object polygon.
It also requires gnuplot>=5.2 since it uses indexing of datablock lines. Hence, the data should already be in a datablock without empty or commented lines. But how to get a file into a datablock?
Either something like:
set table $Data
plot FILE u 1:2:3:4:5:6:7 w table
unset table
or alternatively see here: gnuplot: load datafile 1:1 into datablock
Script:
### draw some colored triangles from a datablock
reset session
$Data <<EOD
0 0 2 1 1 2 0xff0000
5 1 3 2 4 4 0x00ff00
3 3 2 5 1 4 0x0000ff
EOD
vx(n,t) = word($Data[n],t*2-1) # vertex x-coordinate
vy(n,t) = word($Data[n],t*2) # vertex y-coordinate
color(n) = word($Data[n],7) # triangle color
set linetype 1 lc rgb "black"
do for [n=1:|$Data|] {
set obj n polygon from vx(n,1),vy(n,1) to vx(n,2),vy(n,2) to vx(n,3),vy(n,3) to vx(n,1),vy(n,1)
set obj n fc rgb color(n) fs solid 0.5 border lt 1 lw 3
}
set size square
set xrange[0:5]
set yrange[0:5]
plot NaN notitle # or plot something else
### end of script
Result:
Addition:
Alternatively, similar to Ethan's solution, plotting triangles instead of drawing triangles, but without using a temporary file on disk (but a datablock). The result is identical to the graph above. I haven't tested whether drawing or plotting is faster and/or more efficient if you want to draw/plot thousands of triangles.
Script:
### plot some colored triangles from a datablock
reset session
$Data <<EOD
0 0 2 1 1 2 0xff0000
5 1 3 2 4 4 0x00ff00
3 3 2 5 1 4 0x0000ff
EOD
vx(n,t) = word($Data[n],t*2-1) # vertex x-coordinate
vy(n,t) = word($Data[n],t*2) # vertex y-coordinate
color(n) = word($Data[n],7) # triangle color
set print $Triangles
do for [n=1:|$Data|] {
print sprintf("%s %s %s\n%s %s 0\n%s %s 0\n%s %s 0\n\n", \
vx(n,1),vy(n,1),color(n), vx(n,2),vy(n,2), vx(n,3),vy(n,3), vx(n,1),vy(n,1))
}
set print
set size square
set xrange[0:5]
set yrange[0:5]
set linetype 1 lc rgb "black" lw 3
set style fill solid 0.5
plot $Triangles u 1:2:3 w filledcurves lc rgb var notitle
### end of script

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:

categorising points by using of gnuplot

I am going to plot a file containing 4 columns. first and second column are x and y respectively. I want to categorize these point based on the third and fourth column. In fact, the third column should display the color (red or blue) of point and the fourth column should determine its type (square or circle ). how could I reach to this goal by gnu-plot?
I should mention that I tried this, by it does not work!
set style line 1 lc rgb 'red' pt 7
set style line 2 lc rgb 'red' pt 7
set style line 3 lc rgb 'blue' pt 9
set style line 4 lc rgb 'blue' pt 9
plot 'data' w ($3= 1 && $4= 1) ? p ls 1 \
: ($3= 1 && $4= 2) ? p ls 2 \
: ($3= 2 && $4= 1) ? p ls 3 \
: ($3= 2 && $4= 2) ? p ls 4
Please check help points. From the manual:
plot DATA using x:y:pointsize:pointtype:color \
with points lc variable pt variable ps variable
You don't show sample data. If you can adjust your data, the easiest would be the following below.
If you want to set the color by name in your file, check this.
Code:
### variable pointtype and color
reset session
$Data <<EOD
1 2 5 0xff0000
3 4 7 0xff0000
5 6 5 0x0000ff
7 8 7 0x0000ff
EOD
plot $Data u 1:2:3:4 w p ps 5 pt var lc rgb var
### end of code
Result:

Resources