Histogram Gnuplot mixing Clustered/Stacked - gnuplot

I have a histogram consisiting in 6 columns. I would like to clustered them in pairs to have two clustered group made of two stacked colums. I almost done it, except that the legend is has double the entries that I want and that the graph is not centered
set terminal epslatex standalone color size 4.0in,3.0in background rgb "white"
set output 'massFlowSection.tex'
set xtics("ex1" 1, "ex2" 2, "ex3" 3)
#set yrange [0:100]
set style fill solid border -1
#set key invert
#set grid
num_of_ksptypes=2
set boxwidth 0.5/num_of_ksptypes
dx=0.5/num_of_ksptypes
offset=-0.12
plot 'data1.dat' using ($1+offset):($2+$3+$4) title "par3" with boxes, \
'' using ($1+offset):($3+$4) title "par2" with boxes, \
'' using ($1+offset):($4) title "par1" with boxes, \
'data2.dat' using ($1+offset+dx):($2+$3+$4) title "par3" with boxes, \
'' using ($1+offset+dx):($2+$3) title "par2" with boxes, \
'' using ($1+offset+dx):($4) title "par1" with boxes
The entry data are file data1.dat
area par3 par2 par1
1 0.0078 0.0211 0
2 0.0139 0.0302 0
3 0.0169 0 0.119
and file data2.dat
nr par3 par2 par1
1 0.0083 0.0233 0
2 0.0151 0.0302 0
3 0.0173 0 0.211
This is the result

The following might be a starting point for further tweaking.
I tried to keep it general, such that you can easily add more columns or rows.
In your code you are summing up the column values "manually" $2+$3+$4. There are certainly ways to sum up columns "automatically".
But, I allowed myself to transpose your data, because I found it easier. Let me know if you can live with it. Since gnuplot has no transpose function, you either have to implement it yourself or use external software. The latter, I usually try to avoid because of platform-independence. I guess there is also a way to do the same plot for your original data.
I prefer the plotting style with boxxyerror instead of with boxes which is always starting from zero.
Actually, the last plot command is plotting nothing but just getting somehow the legend. This is still suboptimal. A additional declaration could be added which tells you which stack is Data1 and which is Data2.
Code:
### Histogram stacked and grouped
reset session
$Data1 <<EOD
area "ex 1" "ex 2" "ex 3"
par1 0 0 0.119
par2 0.0211 0.0302 0
par3 0.0078 0.0139 0.0169
EOD
$Data2 <<EOD
nr "ex 1" "ex 2" "ex 3"
par1 0 0 0.211
par2 0.0233 0.0302 0
par3 0.0083 0.0151 0.0173
EOD
set key top left
set style fill solid border -1
Cols = 3
Groups = 2
GroupGap = 0.2
BoxScale = 0.9
BoxWidth = (1.0-GroupGap)/Groups
Offset(g,i) = i-1.5+GroupGap/2.0 + BoxWidth/2 +(g-1)*BoxWidth
myXtic(i) = columnhead(i)
BoxL(g,i) = Offset(g,i)-BoxWidth/2.*BoxScale
BoxR(g,i) = Offset(g,i)+BoxWidth/2.*BoxScale
set xrange [0.5:Cols+0.5]
array myPalette[6] = [0xff0000, 0x00ff00, 0x0000ff, 0xffaaaa, 0xaaffaa, 0xaaaaff]
myColors(n) = myPalette[n+1+(g-1)*3]
set table $Legend
plot $Data1 u (strcol(1)) w table
unset table
plot \
for [i=2:Cols+1] $Data1 u (g=1,i-1):(int($0)?sum:sum=0):\
(BoxL(g,i)):(BoxR(g,i)):(sum):(sum=sum+column(i)):(myColors($0)) \
skip 1 w boxxy lc rgb var not, \
for [i=2:Cols+1] $Data2 u (g=2,i-1):(int($0)?sum:sum=0):\
(BoxL(g,i)):(BoxR(g,i)):(sum):(sum=sum+column(i)):(myColors($0)) \
skip 1 w boxxy lc rgb var not, \
for [i=2:|$Legend|] $Data1 u (g=1,i-1):(NaN):(myColors(i-2)): \
xtic(columnhead(i)) w boxes lc rgb var ti word($Legend[i],1)
### end of code
Result:

Related

How to add vertical lines with label using gnuplot?

I have this script to plot data from a CSV file using gnuplot. I want to add 3 vertical lines at different times on the plot to show where I changed the workload of my experiment. I was trying to do it with vector but it was messing the data already plotted. I attached my chart and added manually the vertical blue line as an example of what I want.
#!/usr/bin/gnuplot
# set grid
set key under left maxrows 1
set style line 1 lc rgb '#E02F44' lt 1 lw 1 ps 0.5 pt 7 # input throughput
set style line 2 lc rgb '#FF780A' lt 1 lw 1 ps 0.5 pt 1 # output throughput
set style line 3 lc rgb '#56A64B' lt 1 lw 1 ps 0.5 pt 2 # average processing latency
set style line 4 lc rgb '#000000' lt 1 lw 1 ps 0.5 pt 3 # 99th percentile processing latency
set terminal pdf
set pointintervalbox 0
set datafile separator ','
set output "efficiency-throughput-networkbuffer-baseline-TaxiRideNYC-100Kpersec.pdf"
set title "Throughput vs. processing latency consuming 50K r/s from the New York City (TLC)"
set xlabel "time (minutes)"
set ylabel "Throughput (K rec/sec)"
set y2label "processing latency (seconds)"
set ytics nomirror
set y2tics 0, 1
set xdata time # tells gnuplot the x axis is time data
set timefmt "%Y-%m-%d %H:%M:%S" # specify our time string format
set format x "%M" # otherwise it will show only MM:SS
plot "throughput-latency-increasing.csv" using 1:(column(2)/1000) title "IN throughput" with linespoints ls 1 axis x1y1 \
, "throughput-latency-increasing.csv" using 1:(column(10)/1000) title "OUT throughput" with linespoints ls 2 axis x1y1 \
, "throughput-latency-increasing.csv" using 1:(column(18)/1000) title "avg. latency" with linespoints ls 3 axis x1y2 \
, "throughput-latency-increasing.csv" using 1:(column(26)/1000) title "99th perc. latency" with linespoints ls 4 axis x1y2 \
#, "" using 1:($1):(3):(0) notitle with vectors nohead
My data file is:
"Time","pre_aggregate[0]-IN","pre_aggregate[1]-IN","pre_aggregate[2]-IN","pre_aggregate[3]-IN","pre_aggregate[4]-IN","pre_aggregate[5]-IN","pre_aggregate[6]-IN","pre_aggregate[7]-IN","pre_aggregate[0]-OUT","pre_aggregate[1]-OUT","pre_aggregate[2]-OUT","pre_aggregate[3]-OUT","pre_aggregate[4]-OUT","pre_aggregate[5]-OUT","pre_aggregate[6]-OUT","pre_aggregate[7]-OUT","pre_aggregate[0]-50","pre_aggregate[1]-50","pre_aggregate[2]-50","pre_aggregate[3]-50","pre_aggregate[4]-50","pre_aggregate[5]-50","pre_aggregate[6]-50","pre_aggregate[7]-50","pre_aggregate[0]-99","pre_aggregate[1]-99","pre_aggregate[2]-99","pre_aggregate[3]-99","pre_aggregate[4]-99","pre_aggregate[5]-99","pre_aggregate[6]-99","pre_aggregate[7]-99"
"2020-04-27 10:31:00",1428.05,1274.4666666666667,1364.6166666666666,1384.4666666666667,1327.3,1376.5,1390.9166666666667,1418.35,1428.05,1274.4666666666667,1364.6333333333334,1384.4666666666667,1327.3,1376.5,1390.9166666666667,1418.35,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1
"2020-04-27 10:31:15",1463.5833333333333,1452.3666666666666,1346.7333333333333,1380.3833333333334,1429.4833333333333,1431.6833333333334,1442.85,1425.15,1463.5833333333333,1452.3666666666666,1346.7333333333333,1380.3833333333334,1429.4833333333333,1431.6833333333334,1442.85,1425.15,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1
"2020-04-27 10:31:30",1393.4666666666667,1396.65,1369.55,1381.3833333333334,1336.8,1434.5166666666667,1440.0833333333333,1399.2833333333333,1393.45,1396.65,1369.55,1381.3833333333334,1336.8,1434.5166666666667,1440.0833333333333,1399.2833333333333,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1
"2020-04-27 10:31:45",1404.8833333333334,1448.5333333333333,1313.9,1308.1,1359.6333333333334,1329.5166666666667,1338.4166666666667,1481.5666666666666,1404.8833333333334,1448.5333333333333,1313.9,1308.1,1359.6333333333334,1329.5166666666667,1338.4166666666667,1481.5833333333333,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1
Of course you can plot your lines and labels. In the example below I'm using the newer syntax compared to set xdata time. Which requires timecolumn(1,myTimeFmt) and e.g. set format x "%M" time.
Your date is in double quotes, so you have to define the timeformat using single quotes including the double quotes.
Furthermore, you are using absolute times, so your lines ideally use the same format. You can put it into a datablock. I hope you can adapt the code to your needs.
Code:
### vertical lines with labels on time axis
reset session
$myLines <<EOD
"2020-04-27 10:34:00"
"2020-04-27 10:39:20"
"2020-04-27 10:43:50"
"2020-04-27 10:48:00"
EOD
myTimeFmt = '"%Y-%m-%d %H:%M:%S"'
StartDate = '"2020-04-27 10:30:00"'
EndDate = '"2020-04-27 10:52:00"'
set format x "%M" time
set xrange [strptime(myTimeFmt,StartDate):strptime(myTimeFmt,EndDate)]
yLow = 1.4
yHigh = 3.5
set tmargin screen 0.90
plot '+' u (strptime(myTimeFmt,StartDate)+$0*60):(rand(0)*3+0.5) w l lc rgb "red" notitle, \
$myLines u (timecolumn(1,myTimeFmt)):(yHigh):("Workload\nchanged") w labels right offset -0.5,1.5 not, \
$myLines u (timecolumn(1,myTimeFmt)):(yLow):(0):(yHigh-yLow) w vec lc rgb "blue" lw 2 nohead not
### end of code
Result:

Drawing a simple polygon using Gnuplot with "angle signs"

Disclaimer: I am new to Gnuplot, and I need to plot some "simple" things for my studies.
I want to plot a part of a polygon with some names and vectors added.
The picutre below was created with Euklid Dynageo, and I am now trying to create this with Gnuplot.
The biggest problem I am facing right now is the labeling u,v,w and adding the angles to the plot. I think I would use vectors and lines.
Do you now a 'simple' way to create this plot?
If you really need to use Gnuplot for this, you have to make it all manually by placing various objects, labels and arrows (keep in mind that complex plots will be cumbersome). A minimal example for two arrows and alpha_1, similar like in your example, could like like this:
# two arrows:
set arrow 1 from 0,0 to sqrt(2)/2,sqrt(2)/2
set arrow 2 from 0,0 to 1,0
# the alpha_1 symbol:
set label 1 '{/Symbol a}_1' at 0.2,0.1 front
# the filled yellow arc (from 0 to 45deg):
set style fill solid 1.0 border
set object 1 circle at 0,0 radius 0.2 arc[0:45] fc rgb "yellow"
# proper ratio, range, and plot 'something':
set xrange[-0.1:1.1]
set yrange[-0.1:1.1]
set size ratio 1
plot 1/0
Lookup the manual for possible object properties.
gnuplot is a very versatile plotting tool, but certainly not optimized for such tasks. For this type of drawing maybe Inkscape or others tools might be better choices, especially for interactive drawing by clicking, dragging and snapping.
And as #JackGlasshard already mentioned, of course you can do such graphs with gnuplot which will be rather time consuming if you do it manually.
Alternatively, you can facilitate the work if you use a "template".
Creating such a template probably only makes sense if you need to create more than one drawing.
Just for fun and feasibility, I tried to create such a template for general use to make such graphs easier.
For the input data you need 3 datablocks (without headers)
$Points: # no., x, y, label, xoff, yoff, pt, ps, color
you define: point number, x-coordinate, y-coordinate, point label, x-offset, y-offset, pointtype, pointsize, point color
$Vectors: # p1, p2, label, arrow, lw, dt, xoff, yoff, color
you define: first point number, second point number, label, arrowsstyle (-1=backhead, 0=nohead, 1=head, 2=heads), linewidth, dashtype, x-offset, y-offset, vector color
$Angles: # p1, p2, p3, r, label, aoff, roff, color
you define: 1st point number, 2nd point number (=angle center point), 3rd point number, radius, label, angular label offset, radial label offset, color
Now, you only have to change the data part of the script for your custom graph. In case you want to insert "invisible" vector starting or end points, simply set pointsize to 0 in $Points. The plotting of the variable arrowheads is a bit cumbersome because of the issue mentioned in this question.
For sure, more features and more flexibility can be added to the template. No warranty that the script is free of bugs. There is certainly room for improvements.
Update: (linewidth and dashtype added)
Since there is no variable linewidth (lw var) and no variable dashtype (dt var)
you have to plot each line separately in a for loop and every ::n::n.
Furthermore, I noticed that the order of variable pointsize (ps var) and and variable pointtype (pt var) apparently has changed from gnuplot 5.2 to 5.4. Not sure whether this intentional or a "bug".
The version below has the order for gnuplot 5.4.
Script:
### drawing sketch with points, vectors and angles
reset session
# no., x, y, label, xoff, yoff, pt, ps, color
$Points <<EOD
1 1 1 "" 0 0 5 1 0xff0000
2 10 2 V_{i-1} 0 0 5 1 0xff0000
3 15 10 V_i 0 0 5 1 0xff0000
4 4 12 X -1.5 0 5 1 0xff0000
5 14 16 V_{i+1} 0 0 5 1 0xff0000
6 5 20 "" 0 0 5 1 0xff0000
EOD
# p1, p2, label, arrow, lw, dt, xoff, yoff, color
# arrows: -1=backhead, 0=nohead, 1=head, 2=heads
$Vectors <<EOD
1 2 "" 0 1.0 1 0 0 0xff0000
2 3 "" 0 2.0 1 0 0 0x000000
3 5 "" 0 1.5 3 0 0 0x000000
4 2 w 1 1.0 1 1.0 0 0x000000
4 3 v 1 1.0 1 0 0.7 0x0000ff
4 5 u 1 1.0 1 0 0.7 0x000000
5 6 "" 0 1.0 1 0 0 0x000000
EOD
# p1, p2, p3, r, label, aoff, roff, color
# p2=angle center point
$Angles <<EOD
2 4 3 4.0 α_{i-1} 7.0 0.5 0xffcccc
3 4 5 4.5 α_i 3.0 0.7 0xffffcc
EOD
### end of data input
### start of template
# point/vector coordinates
px(n,m) = real(word($Points[int(word($Vectors[n],m))],2)) # x coordinate of point n
py(n,m) = real(word($Points[int(word($Vectors[n],m))],3)) # y coordinate of point n
vxd(n) = px(n,2)-px(n,1) # vector delta x
vyd(n) = py(n,2)-py(n,1) # vector delta y
vxc(n) = (px(n,2)+px(n,1))/2. # vector center x
vyc(n) = (py(n,2)+py(n,1))/2. # vector center y
lw(n) = real(word($Vectors[n],5))
dt(n) = int(word($Vectors[n],6))
# angles
as(n) = int(column(5)+2) # arrow style
ax(n) = real(word($Points[int(word($Angles[int(column(0)+1)],n))],2)) # angle center x
ay(n) = real(word($Points[int(word($Angles[int(column(0)+1)],n))],3)) # angle center y
set angle degrees
Angle(x0,y0,x1,y1) = (_dx=x1-x0, _dy=y1-y0, _L=sqrt(_dx**2 + _dy**2), _L==0 ? NaN : \
(_dy>=0 ? acos(_dx/_L) : -acos(_dx/_L) ))
a1(m) = Angle(ax(2),ay(2),ax(1),ay(1)) # starting angle
a2(m) = Angle(ax(2),ay(2),ax(3),ay(3)) # end angle
set style arrow 1 backhead filled # -1
set style arrow 2 nohead filled # 0
set style arrow 3 head filled # 1
set style arrow 4 heads filled # 2
set size ratio -1 # ensure same x- and y-ratio
set key noautotitle
set xrange [0:22]
set yrange [0:22]
set mxtics 5
set mytics 5
set grid x,y,mx,my
set style fill solid 0.5 border lc "black"
plot $Angles u (ax(2)):(ay(2)):4:(a1(0)):(a2(0)):8 w circles lc rgb var, \
'' u (ax(2)+($4*0.5+$7)*cos(0.5*(a1(0)+a2(0))+$6)): \
(ay(2)+($4*0.5+$7)*sin(0.5*(a1(0)+a2(0))+$6)):5 w labels font "Times New Roman,13" center, \
for [i=1:|$Vectors|] $Vectors \
u (px(i,1)):(py(i,1)):(vxd(i)):($4==-1?vyd(i):NaN):9 every ::i-1::i-1 w vectors lc rgb var lw lw(i) dt dt(i) filled backhead, \
for [i=1:|$Vectors|] '' \
u (px(i,1)):(py(i,1)):(vxd(i)):($4== 0?vyd(i):NaN):9 every ::i-1::i-1 w vectors lc rgb var lw lw(i) dt dt(i) filled nohead, \
for [i=1:|$Vectors|] '' \
u (px(i,1)):(py(i,1)):(vxd(i)):($4== 1?vyd(i):NaN):9 every ::i-1::i-1 w vectors lc rgb var lw lw(i) dt dt(i) filled head, \
for [i=1:|$Vectors|] '' \
u (px(i,1)):(py(i,1)):(vxd(i)):($4== 2?vyd(i):NaN):9 every ::i-1::i-1 w vectors lc rgb var lw lw(i) dt dt(i) filled heads, \
for [i=1:|$Vectors|] '' \
u (vxc(i)+$7):(vyc(i)+$8):3:9 every ::i-1::i-1 w labels font ",12" tc rgb var, \
$Points u 2:3:7:8:9 w p ps var pt var lc rgb var, \
'' u ($2+$5):($3+$6):4:9 w labels tc rgb var font ",12" left offset 1,0
### end of script
Result:

Simple heaviside function graphic with gnuplot?

I basically want this (first diagram) done with gnuplot. I've searched and found nothing exactly like this. I can do a good heaviside without the little circles at the end and start of the two lines, but I can't seem to get it with the little circles. Actually, the second diagram would be nice to know too. The third too, but I'm not greedy.
Just for the records and completeness... although you can define a function
H(x) = x<0 ? 0 : 1
If you plot
plot H(x) w l
the line will be continuous at zero and of course without points.
So, another suggestion with just two columns x,y and variable pointtype would be the following.
Code:
### Heaviside function
reset session
$Heaviside <<EOD
-2 0
0 0
0 0.5
0 1
2 1
EOD
set yrange [-1:2]
set ytics 1
unset key
set multiplot layout 3,1
plot $Heaviside u 1:2 w l lc 0, \
'' u 1:($0==1||$0==3?$2:NaN):($0==3?7:6) w p pt var lc 0
plot $Heaviside u 1:2 w l lc 0, \
'' u 1:($0==1||$0==2||$0==3?$2:NaN):($0==2?7:6) w p pt var lc 0
set xrange [0:4]
a = 3
plot $Heaviside u ($1+a):2 w l lc 0, \
'' u ($1+a):($0==1||$0==3?$2:NaN):($0==3?7:6) w p pt var lc 0
unset multiplot
### end of code
Result:
Addition:
A variation with shorter and less confusing plot command, but using 4 columns together with variable pointtype. This will give the same result as above.
Code:
### Heaviside function
reset session
$Heaviside <<EOD
-2 0 NaN NaN
0 0 6 6
0 0.5 NaN 7
0 1 7 6
2 1 NaN NaN
EOD
set yrange [-1:2]
set ytics 1
unset key
set multiplot layout 3,1
plot $Heaviside u 1:2 w l lc 0, \
'' u 1:2:3 w p pt var lc 0
plot $Heaviside u 1:2 w l lc 0, \
'' u 1:2:4 w p pt var lc 0
set xrange [0:4]
a = 3
plot $Heaviside u ($1+a):2 w l lc 0, \
'' u ($1+a):2:3 w p pt var lc 0
unset multiplot
### end of code
Addition 2:
In order to finalize the answer, here is an approach to plot functions containing the Heaviside function.
Instead of plotting from a datablock with fixed x-values (as in the two examples above) it uses the current x-range. Note, for example the syntax plot '+' u 1:(sin($1)) is basically identical with plot sin(x).
Apparently, setting the line color via lc rgb -1 does not plot a line, which can be used here to interrupt the line. You may want to increase the samples, e.g. set samples 300 to avoid a gap between the points and the function.
Code:
### plotting Heaviside function and functions containing Heaviside function
# including line interruption and inclusion/exclusion points
reset session
Heaviside(x,a) = x<a ? 0 : 1 # definition of Heaviside function
array Hpoints[2] = [6,7] # array for plotting "Heaviside points"
Hcolor(x) = (x0=x1, x1=x, x0<a && x1>=a ? -1 : 0xff0000) # set color -1 for line interruption
dx(n) = 1e-3*(2*n-1) # small dx to get y-value of points close to break
f(x,a) = 50/(x**2+2)*cos(4*x) * Heaviside(x,a)
unset key
set multiplot layout 2,1
a = 2.0
set yrange[-1:2]
plot x1=NaN '+' u 1:(Heaviside(x,a)):(Hcolor(x)) w l lc rgb var, \
Hpoints u (a):(Heaviside($1,a)):(Hpoints[$0+1]) w p pt var lc rgb Hcolor(NaN)
a= 0
set samples 300
set yrange[-25:35]
plot x1=NaN '+' u 1:(f(x,a)):(Hcolor(x)) w l lc rgb var, \
Hpoints u (a):(f(a+dx($0),a)):(Hpoints[$0+1]) w p pt var lc rgb Hcolor(NaN)
unset multiplot
### end of code
Result:
I created the following datafile (mind the two empty lines):
-2 0 0 1
0 0 2 1
0 0 0 1
and ran the following gnuplot commands:
set yrange [-2:2]
plot "file" using 1:2 with lines,\
"" using 3:4 with lines, \
"" index 1 using 1:2 with points pointtype 6, \
"" index 1 using 3:4 with points pointtype 7
Fix the colours to your liking.

Separate key (legend) for colors and markers

I have a plot with several types of objects (each read from a separate file). I'm plotting the same several functions for all of them, all on the same graph (same X-axis).
I set the markers (pt) explicitly for each, and the color (lc), so the same object has the same marker, but the same function has the same color. As an example we have 2 files, one for each object (| is just to separate the files here):
0 0 0 | 0 1 1
1 1 2 | 1 1 2
Let's call the left file A, the right B. Column 1 in each file is the x axis, column 2 is using 1:2, and column 3 is using 1:3. So using the above files in an interactive session:
gnuplot> plot "A" using 1:2 with lp pt 1 lc 'black'
gnuplot> replot "A" using 1:3 with lp pt 1 lc 'red'
gnuplot> replot "B" using 1:2 with lp pt 2 lc 'black'
gnuplot> replot "B" using 1:3 with lp pt 2 lc 'red'
we get:
Is it possible to have the key separated, so A/B appear next to their respective marker, and the function name ("using...") appears next to a line (or anything) with the appropriate color?
Right now by omitting titles (notitle in the plot command) I can get one or the other, though I would have to settle on some uniform arbitrary marker/color (depending on what I chose to set as key). Can I:
Get two keys somehow? - Preferably setting the missing attribute (color or marker) to something not in the plot.
If not, can I customize a manual legend somehow?
I am not fully sure what you want to achieve, nevertheless as for the splitting of the key, I don't think that Gnuplot has some "out-of-the-box" feature for this. However, you could (ab)use multiplot to achieve this effect. The idea is basically to generate two overlapping plots - one with points and one with lines - and to position the keys independently:
set terminal pngcairo rounded font ",16"
set output 'fig.png'
$A << EOD
0 0 0
1 1 2
EOD
$B << EOD
0 1 1
1 1 2
EOD
set multiplot
set xtics out nomirror
set ytics out nomirror
eps = 0.1
set lmargin at screen eps
set rmargin at screen 1 - eps/2
set bmargin at screen eps
set tmargin at screen 1 - eps/2
#common key settings
set key left top Left reverse spacing 1.5
set key at screen 0.1,screen 1-eps
plot \
$A u 1:2 with p ps 1.5 pt 1 lc 'black' t 'A', \
$A u 1:3 with p ps 1.5 pt 1 lc 'red' t 'A' , \
$B u 1:2 with p ps 1.5 pt 2 lc 'black' t 'B', \
$B u 1:3 with p ps 1.5 pt 2 lc 'red' t 'B'
unset border; unset xtics; unset ytics
set key at screen 0.3,screen 1-eps
plot \
$A u 1:2 with l lc 'black' t 'using 1:2', \
$A u 1:3 with l lc 'red' t 'using 1:3', \
$B u 1:2 with l lc 'black' t '', \
$B u 1:3 with l lc 'red' t ''
This would give you:

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