Adding vertical marker lines in gnuplot for histogram - gnuplot

There are a few instructions to get vertical lines in gnuplot when plotting functions. Like using the set arrow function. I need this functionality for a histogram and it turns out the histogram has different position of 0.0 on X axis. In my case the X axis markers are just strings from the data file.
When plotting the histogram it would be so nice to have the mean, +-3sigma and maybe the X=0 point marked by vertical lines from top to bottom of the plot in fat colored solid lines.
My histogram code:
set boxwidth 1.0 absolute
set style line 1 lc rgb 'skyblue'
set style fill solid border lt -1
set style data histogram
set style histogram clustered gap 0.0
set xtics in rotate by 90 offset first +0.5,0 right
set xlabel
set ylabel 'Count'
set terminal unknown
plot 'histo.raw' using 3
set title 'data'
set yrange [0:GPVAL_DATA_Y_MAX*1.2]
set term X11
plot 'histo.raw' using 3:xtic(2) ls 1 title columnheader(1)
set arrow 1 from 0.0,0.0 to 0.0,GPVAL_DATA_Y_MAX*1.2 nohead
My data:
"data"
0 "-INF -> -5.0" 0 0.00
1 " -5.0 -> -4.5" 0 0.00
2 " -4.5 -> -4.0" 2 0.03
3 " -4.0 -> -3.5" 4 0.06
4 " -3.5 -> -3.0" 3 0.05
5 " -3.0 -> -2.5" 5 0.08
6 " -2.5 -> -2.0" 19 0.30
7 " -2.0 -> -1.5" 49 0.78
8 " -1.5 -> -1.0" 193 3.07
9 " -1.0 -> -0.5" 527 8.39
10 " -0.5 -> +0.0" 1289 20.53
11 " +0.0 -> +0.5" 1878 29.90
12 " +0.5 -> +1.0" 1411 22.47
13 " +1.0 -> +1.5" 636 10.13
14 " +1.5 -> +2.0" 178 2.83
15 " +2.0 -> +2.5" 56 0.89
16 " +2.5 -> +3.0" 17 0.27
17 " +3.0 -> +3.5" 9 0.14
18 " +3.5 -> +4.0" 4 0.06
19 " +4.0 -> +4.5" 0 0.00
20 " +4.5 -> +5.0" 0 0.00
21 " +5.0 -> +INF" 0 0.00
The set arrow function puts the line in the wrong spot.
set arrow 1 from 0.0,0.0 to 0.0,GPVAL_DATA_Y_MAX*1.2 nohead
In this data
mean= 0.2743
sigma= 0.7491
Thanks for your ideas.
Gert

I found that the histogram bars are defining their own X coordinates counting left to right. As I have 22 data rows for 22 histogram bars adding 11.0 to the line position does the job.
set boxwidth 1.0 absolute
set style line 1 lc rgb 'skyblue'
set style fill solid border lt -1
set style data histogram
set style histogram clustered gap 0.0
set xtics in rotate by 90 offset first +0.5,0 right
set xlabel
set ylabel 'Count'
set terminal unknown
plot 'histo.raw' using 3
set title 'data'
set yrange [0:GPVAL_DATA_Y_MAX*1.2]
set terminal png size 1200,800
set output 'histo.png'
mean= +0.2743
sdev= +0.7491
lboffs= 0.2
set arrow from 11.0 + mean,0.0 to 11.0 + mean ,GPVAL_DATA_Y_MAX*1.2 nohead lw 2 lc rgb "dark-green"
set arrow from 11.0 + mean - 3 * sdev,0.0 to 11.0 + mean - 3 * sdev ,GPVAL_DATA_Y_MAX*1.2 nohead lw 2 lc rgb "red"
set arrow from 11.0 + mean + 3 * sdev,0.0 to 11.0 + mean + 3 * sdev ,GPVAL_DATA_Y_MAX*1.2 nohead lw 2 lc rgb "red"
set arrow from 11.0,0.0 to 11.0,GPVAL_DATA_Y_MAX*1.2 nohead lw 2 lc rgb "blue"
set label "Mean" at 11.0 + mean + lboffs,GPVAL_DATA_Y_MAX*1.1 tc rgb "dark-green"
set label "+3%" at 11.0 + mean + 3 * sdev + lboffs,GPVAL_DATA_Y_MAX*1.1 tc rgb "red"
set label "-3%" at 11.0 + mean - 3 * sdev + lboffs,GPVAL_DATA_Y_MAX*1.1 tc rgb "red"
plot 'histo.raw' using 3:xtic(2) ls 1 title columnheader(1)
set output
set term X11

Related

gnuplot: How to create colored grid regions, not just colored grid lines?

I am using "gnuplot 5.2 patchlevel 2". I am trying to create background grid colored-columns or colored-areas like the picture below. So far, I am only able to color the grid-lines. But I want to color the grid areas. What is the best way? Here is my code:
set terminal svg
set output 'out.svg'
set key off
set xlabel 'X'
set ylabel 'Y'
set title 'Data'
set grid
set grid xtics lw 0.25 lc rgb "#ff0000" # line only, but I want to color the whole area
#unset grid
#set grid ytics lt 0 lw 1 lc rgb "#0000ff"
set xrange [0:4]
set yrange [0:100]
set tics scale 0.5
set xtics nomirror
set ytics nomirror
set style fill solid noborder
set linetype 1 lc rgb 'red' lw 0.35
set linetype 2 lc rgb '#009900'
set linetype 3 lc rgb 'black' lw 0.5
set boxwidth 0.5 relative
set style fill solid border lc rgb "black"
plot "data.txt" using 1:2:4:3:5:($5 < $2 ? 1 : 2) linecolor variable with candlesticks, \
"data.txt" using 1:6 with lines lt 3, \
"data.txt" using 1:5:7 with filledcurves fs transparent solid 0.3 lc rgb "blue"
And here is my sample data.txt file for the plotting:
1 10 30 5 20 23 29
2 25 45 10 30 34 37
3 30 50 20 25 47 53
You could use a dummy function like [x=0:16:1] '+' us (x/2):(100/(int(x)%4!=1)) with filledcurves x1.
Every fourth point generates a NaN and interrupts the curve.
$data <<EOD
1 10 30 5 20 23 29
2 25 45 10 30 34 37
3 30 50 20 25 47 53
5 10 30 5 20 23 29
7 25 45 10 30 34 37
8 30 50 20 25 47 53
EOD
set style fill solid noborder
set linetype 1 lc rgb 'red' lw 0.35
set linetype 2 lc rgb '#009900'
set linetype 3 lc rgb 'black' lw 0.5
set boxwidth 0.5 relative
set style fill solid border lc rgb "black"
plot sample [x=0:16:1] '+' us (x/2):(100/(int(x)%4!=1)) with filledcurves x1 fc rgb "#EEEEEE",\
$data using 1:2:4:3:5:($5 < $2 ? 1 : 2) linecolor variable with candlesticks, \
$data using 1:6 with lines lt 3, \
$data using 1:5:7 with filledcurves fs transparent solid 0.3 lc rgb "blue"
This function could be also assigned to the y2 axis with fixed y2range, which might be more handy for interactive plots with zooming.

Draw a bended arrow between two points in gnuplot

I am producing the figure below using the following gnuplot code. I want to draw a bended arrow from the point labeled l=0 to l=1 with head.
Code
reset session
# Ranges
set xrange [-1:6]
set yrange [-2:1]
# Term options
set terminal postscript eps
set termoption font "Times, 30"
# set termoption
set style line 1 lc rgb 'black' lw 3 lt 1 pt 7 ps 2
# Data points
$DATA<<EOD
0 0
1 0
2 0
3 0
4 0
5 0
6 0
EOD
set output "Anderson_lattice.eps"
# set arrow
set arrow 1 from -0.5, -1.5 to 5.5, -1.5 lc rgb 'black' lw 5
set arrow 2 from -0.5, -1.5 to -0.5, -0.5 lc rgb 'black' lw 5
set label 1 "{/Times-Italic=30 {/Symbol e}_{l}}" at -0.75, -0.3 tc rgb "black"
set arrow 3 from -0.25, -1.0 to 0.25, -1.0 ls 1 nohead
set arrow 5 from 1 - 0.25, -0.75 to 1 + 0.25, -0.75 ls 1 nohead
set arrow 6 from 2 - 0.25, -0.5 to 2 + 0.25, -0.5 ls 1 nohead
set arrow 7 from 3 - 0.25, -1.35 to 3 + 0.25, -1.35 ls 1 nohead
set arrow 8 from 4 - 0.25, -1.0 to 4 + 0.25, -1 ls 1 nohead
set arrow 9 from 5 - 0.25, -0.85 to 4 + 0.25, -0.85 ls 1 nohead
set arrow 10 from 6 - 0.25, -1.25 to 6 + 0.25, -1.25 ls 1 nohead
set label 2 "{/Times-Italic=30 sites}" at 5.5, -1.65 tc 'black'
set label 3 "{/Times-Italic=30 l=0}" at 2.7, -0.25 tc 'black'
set label 4 "{/Times-Italic=30 l=1}" at 1 + 2.7, -0.25 tc 'black'
unset xtics; unset ytics; unset border
plot $DATA using 1:2 with p ls 1 notitle
unset output
Result
How do I do that?
I'm not aware that gnuplot offers a feature for directly drawing a bent arrow.
Edit:
(I removed my initial approach since it has no advantage over using Cubic Bézier. And added some more flexibility to the second approach.)
I completely agree with #GRSousaJr that Cubic Bézier curves give much more flexibility in drawing bent arrows. At the same time you can also draw straight arrows.
Based on #GRSousaJr's approach, my suggestions would be the following:
instead of entering absolute values for the control points, I would prefer relative or absolute angles and relative distances. This has the advantage that you don't have to care about absolute numbers, especially when two arrows should have the same proportions but have different absolute start/endpoints.
All parameters for the arrows are in the datablock $myArrows.
Some explanations:
for the Cubic Bézier curves 4 points are used: p0,p1,p2,p3, where p0 and p3 are the start and end points, respectively. p1 and p2 are points which control the curvature. p0x, p0y, ... p3x, p3y are the x and y components, respectively.
in contrast to #GRSousaJr's solution the control points p1 and p2 are not given in absolute values but calculated from p0 and p3 and the angles a0 and a3 and the radii r0 and r3.
the angles of the arrow at the points p0 and p3 can be given absolute or relative to the direction of p0 to p3. The parameter e tells which end has relative angle and which end absolute angle. 0=angles at both ends relative, 1=start angle relative, end angle absolute, 2=start angle absolute, end angle relative, 3=angles at both ends absolute. For the relative angle you first need to calculate the angle between p0 and p3 (function AngleP0P3())
the distance of the control points p1 and p2 from the points p0 and p3 are given in relative values r0 and r3 with respect to the distance between p0 and p3. That's why there is the function Length(). 0.5 is a good value to start with.
note that the functions AngleP0P3(n) and Length(n) actually do not depend on n. That is just to shorten the code. These functions use the parameters p1x, ..., p3y, and when calling AngleP0P3(0) the function will take the current values of p1x, ..., p3y. This is shorter than e.g. Angle(p0x,p0y,p3x,p3y).
the function ArrowInit(i) is to collect or initialize the values for p1x, ..., p3y from the ith row of datablock $myArrows.
the line of the arrows are simply plotted in a for loop as parametric function in t with the range t[0:1]. For every i in the plot command ArrowInit(i) is called to get the corresponding parameters from the datablock $myArrows.
The angle of the arrow in point p3 is in the direction from p2 to p3, i.e. the tangent of the Bézier curve in point p3. However you don't want the line, but just the arrow. So far, I don't have a better approach than plotting a short vector from 99% of the arrow path to 100% of the arrow path.
Some comments on usage:
in order to "see" the correct angles you specify in $myArrows, your plot has to have the same aspect ratio as your x and y ranges. In the below examples it is x[0:20] and y[0:10], hence, set the aspect ratio of the graph to 0.5, i.e. at the beginning set size 0.5.
the direction of the arrow head is the tangent in point p3. If you have a strong curvature at p3, the arrow head might look "bad", although the arrow head is in the correct angle. In such cases, increase the length r3 a little.
You can also draw straight arrows, see Arrow1. Just set a0=0,a3=0 and e=0.
Tested with gnuplot 5.2.8
Code:
### workaround for bent arrows
reset session
set size ratio 0.5
# p0x p0y a0 r0 p3x p3y a3 r3 e color
$myArrows <<EOD
1 1.00 1.00 0 0.5 3.00 3.00 0 0.5 0 0xff0000
2 3.00 1.00 0 0.5 5.00 3.00 0 0.5 1 0x00c000
3 5.00 1.00 0 0.5 7.00 3.00 0 0.5 2 0x0000ff
4 7.00 1.00 0 0.5 9.00 3.00 0 0.5 3 0xff00ff
5 1.00 4.00 0 0.5 3.00 6.00 90 0.5 0 0xff0000
6 3.00 4.00 0 0.5 5.00 6.00 90 0.5 1 0x00c000
7 5.00 4.00 0 0.5 7.00 6.00 90 0.5 2 0x0000ff
8 7.00 4.00 0 0.5 9.00 6.00 90 0.5 3 0xff00ff
9 1.00 7.00 90 0.5 3.00 9.00 0 0.5 0 0xff0000
10 3.00 7.00 90 0.5 5.00 9.00 0 0.5 1 0x00c000
11 5.00 7.00 90 0.5 7.00 9.00 0 0.5 2 0x0000ff
12 7.00 7.00 90 0.5 9.00 9.00 0 0.5 3 0xff00ff
13 11.00 1.00 45 0.5 13.00 3.00 -45 0.5 0 0xff0000
14 13.00 1.00 45 0.5 15.00 3.00 -45 0.5 1 0x00c000
15 15.00 1.00 45 0.5 17.00 3.00 -45 0.5 2 0x0000ff
16 17.00 1.00 45 0.5 19.00 3.00 -45 0.5 3 0xff00ff
17 11.00 4.00 -45 0.5 13.00 6.00 -45 0.5 0 0xff0000
18 13.00 4.00 -45 0.5 15.00 6.00 -45 0.5 1 0x00c000
19 15.00 4.00 -45 0.5 17.00 6.00 -45 0.5 2 0x0000ff
20 17.00 4.00 -45 0.5 19.00 6.00 -45 0.5 3 0xff00ff
21 11.00 7.00 0 0.5 15.00 9.00 90 0.5 1 0x00c000
22 15.00 7.00 0 0.5 19.00 9.00 0 0.5 1 0x00c000
EOD
set angle degrees
# Angle between p0 and p3 (range: -90° <= angle < 270°), NaN if dx=dy=0
AngleP0P3(n) = (dy=p3y-p0y,dx=p3x-p0x)==0 ? (dy==0 ? NaN : sgn(dy)*90) : \
(dx<0 ? 180 : 0) + atan(dy/dx)
# Parameter e: determines which ends have relative or absolute angles
# 0: both ends relative
# 1: start relative, end absolute,
# 2: start absolute, end relative
# 3: both ends absolute
AngleAbs(i) = int(word($myArrows[i],10)) # to set all arrows equal, use: AngleAbs(i) = 0,1,2, or 3
Angle(i,p) = word($myArrows[i],p) + \
((p==4 && AngleAbs(i)&2) || (p==8 && AngleAbs(i)&1) ? 0 : AngleP0P3(0))
Length(n) = sqrt((p3x-p0x)**2 + (p3y-p0y)**2)
Color(i) = word($myArrows[i],11)
ArrowInit(i) = (p0x=word($myArrows[i],2),p0y=word($myArrows[i],3), \
p3x=word($myArrows[i],6),p3y=word($myArrows[i],7), \
p1x=p0x+Length(0)*word($myArrows[i],5)*cos(Angle(i,4)), \
p1y=p0y+Length(0)*word($myArrows[i],5)*sin(Angle(i,4)), \
p2x=p3x-Length(0)*word($myArrows[i],9)*cos(Angle(i,8)), \
p2y=p3y-Length(0)*word($myArrows[i],9)*sin(Angle(i,8)))
# Cubic Bézier curves function with t[0:1] as parameter
# p0: start point, p1: 1st control point, p2: 2nd control point, p3: endpoint
px(t) = (-p0x + 3*p1x - 3*p2x + p3x)*t**3 + (3*p0x - 6*p1x + 3*p2x)*t**2 + (-3*p0x + 3*p1x)*t + p0x
py(t) = (-p0y + 3*p1y - 3*p2y + p3y)*t**3 + (3*p0y - 6*p1y + 3*p2y)*t**2 + (-3*p0y + 3*p1y)*t + p0y
# set linestyles and arrowstyles
do for [i=1:|$myArrows|] {
set style line i lw 2 lc rgb Color(i)
set style arrow i head size 0.20,15,45 fixed filled ls i
}
set key out noautotitle below
set xrange [0:20]
set xtics 1
set format x ""
set grid xtics ls -1 lc rgb "gray"
set yrange [0:10]
set ytics 1
set format y ""
set grid ytics ls -1 lc rgb "gray"
plot for [i=1:|$myArrows|] [0:1] '+' u (ArrowInit(i),px($1)):(py($1)) w l ls i, \
for [i=1:|$myArrows|] [0:1] '+' u (ArrowInit(i),px(0.99)):(py(0.99)): \
(px(1)-px(0.99)):(py(1)-py(0.99)) every ::0::0 w vec as i, \
$myArrows u 2:3:1 w labels offset 0,-0.7, \
keyentry w l ls 1 ti "both ends relative angles", \
keyentry w l ls 2 ti "start relative, end absolute angle", \
keyentry w l ls 3 ti "start absolute, end relative angle", \
keyentry w l ls 4 ti "both ends absolute angles"
### end of code
exit
Result:
I created (at least in my mind) an "enhanced" version of #theozh's answer, which allows somewhat control over arrow form.
The idea is to use a Bézier curve to draw the bent arrow. The head is drawn as on #theozh's answer, i.e., using vectors. The initial (xi,yi) and final points (xy,yf), as well the control points (xc1,yc1 and xc2,yc2), are passed to a function using call command. The function creates a datafile using theid, like a tag on standard arrow, defined by user, and associates a variavel (e.g. BentArrow_id) name to such datafile. Each created datafile contain:
the control points
the datapoints to create the arrow, and
the datapoints do create head
as three indexable datablocks (0, 1 and 2, respectively), like this:
# Block index 0 (control points)
1.000000e+00 -1.250000e+00
1.250000e+00 0.000000e+00
2.800000e+00 -5.000000e-01
3.000000e+00 -7.500000e-01
# Block index 1 (arrow)
1.000000e+00 -1.250000e+00
1.016539e+00 -1.177084e+00
1.036070e+00 -1.108272e+00
1.058468e+00 -1.043468e+00
... ...
2.927437e+00 -6.862240e-01
2.949992e+00 -7.027320e-01
2.969690e+00 -7.189280e-01
2.986401e+00 -7.347160e-01
3.000000e+00 -7.500000e-01
# Block index 2 (head)
2.986401e+00 -7.347160e-01 1.359880e-02 -1.528400e-02
3.000000e+00 -7.500000e-01 0.000000e+00 0.000000e+00
To draw the bent arrow, the plot command must be composed by three parts:
plot \
...
BentArrow_id i 0 u 1:2 w lp ...,\
BentArrow_id i 1 u 1:2 w lines ...,\
BentArrow_id i 2 u 1:2:3:4 w vectors ...,\
...
Each part corresponds to a piece of arrow (the control points, the arrow itself, and the head, respectively).
To better show the script (called BentArrow.fct) working, consider the example.
reset
set terminal wxt size 500,500
set size ratio -1
set grid ls -1 lc "gray"
unset key
set tics out nomirror
set xrange [-0.25:9.25]
set yrange [-0.25:9.25]
set style arrow 1 head size 0.25,15,45 fixed filled lc "red"
BentArrow(id,xi,yi,x1,y1,x2,y2,xf,yf) = \
sprintf("call 'BentArrow.fct' '%g' '%f' '%f' '%f' '%f' '%f' '%f' '%f' '%f'", \
id, xi,yi, x1,y1, x2,y2, xf,yf )
# id, xi,yi , xc1,yc1, xc2,yc2, xf,yf
eval BentArrow(1, 1.0,1.0, 2.0,2.0, 3.0,0.0, 4.0,1.0)
eval BentArrow(2, 5.0,1.0, 6.0,0.0, 7.0,2.0, 8.0,1.0)
eval BentArrow(3, 1.0,4.0, 2.0,3.0, 3.0,3.0, 4.0,4.0)
eval BentArrow(4, 5.0,4.0, 6.0,5.0, 7.0,5.0, 8.0,4.0)
eval BentArrow(5, 1.0,7.0, 5.0,5.0, 0.0,5.0, 4.0,7.0)
eval BentArrow(6, 5.0,7.0, 5.0,9.0, 6.0,7.0, 8.0,7.0)
CtrlPoints = "w lp ls -1 pt 6 ps 1 pi -1"
StyleArrow = "w lines lc 'red' lw 2"
StyleHead = "w vec as 1"
plot \
BentArrow_1 i 0 u 1:2 #CtrlPoints ,\
BentArrow_1 i 1 u 1:2 #StyleArrow ,\
BentArrow_1 i 2 u 1:2:3:4 #StyleHead ,\
BentArrow_2 i 0 u 1:2 #CtrlPoints ,\
BentArrow_2 i 1 u 1:2 #StyleArrow ,\
BentArrow_2 i 2 u 1:2:3:4 #StyleHead ,\
BentArrow_3 i 0 u 1:2 #CtrlPoints ,\
BentArrow_3 i 1 u 1:2 #StyleArrow ,\
BentArrow_3 i 2 u 1:2:3:4 #StyleHead ,\
BentArrow_4 i 0 u 1:2 #CtrlPoints ,\
BentArrow_4 i 1 u 1:2 #StyleArrow ,\
BentArrow_4 i 2 u 1:2:3:4 #StyleHead ,\
BentArrow_5 i 0 u 1:2 #CtrlPoints ,\
BentArrow_5 i 1 u 1:2 #StyleArrow ,\
BentArrow_5 i 2 u 1:2:3:4 #StyleHead ,\
BentArrow_6 i 0 u 1:2 #CtrlPoints ,\
BentArrow_6 i 1 u 1:2 #StyleArrow ,\
BentArrow_6 i 2 u 1:2:3:4 #StyleHead
The results
Applying the script to your example, the result look like this
Of course the control points are useful just to defining each arrow.
The variable showCtrlPoints = "False" (default "True") is defined to allows hide the control points on final plot.
The script to last example is:
reset
# The data
$levels<<EOD
1 0.5 -1.25
2 0.5 -1.00
3 0.5 -0.75
4 0.5 -0.50
5 0.5 -0.25
6 0.5 -1.25
7 0.5 -1.00
8 0.5 -0.75
9 0.5 -0.50
10 0.5 -0.25
EOD
# Cubic Bézier function
BentArrow(id,xi,yi,x1,y1,x2,y2,xf,yf) = \
sprintf("call 'BentArrow.fct' '%g' '%f' '%f' '%f' '%f' '%f' '%f' '%f' '%f'", \
id, xi,yi, x1,y1, x2,y2, xf,yf )
# Arrow styles
set style arrow 1 head size 0.2,15,45 fixed filled lc "red"
set style arrow 2 head size 0.2,15,45 fixed filled lc "web-green"
set style arrow 3 head size 0.2,15,45 fixed filled lc "blue"
# To levels
set errorbars small
unset key
# Options to drawing the bent arrows
showCtrlPoints = "False"
ArrowPoints = 50
# Calling the function
eval BentArrow(1, 1.00,-1.25, 1.25, 0.00, 2.80,-0.50, 3.00,-0.75)
eval BentArrow(2, 8.00, 0.50, 8.00, 0.00, 5.00, 0.25, 5.00,-0.25)
eval BentArrow(3, 1.00, 0.50, 2.00,-0.25, 9.00, 0.50, 10.0,-0.25)
# Macros
Points = "w p ls -1 pt 7 ps 2"
Levels = "w xerrorbars ls -1 lw 2"
CtrlPoints = "w lp ls -1 pt 6 ps 1 pi -1"
StyleArrow = "w lines lw 2"
StyleHead = "w vectors"
# Allow to toggle between show/hide the control points
CP(n) = showCtrlPoints eq "True" ? n : NaN
plot \
$levels u 1:2 #Points ,\
"" u 1:3:(0.35) #Levels ,\
BentArrow_1 i 0 u 1:(CP($2)) #CtrlPoints ,\
BentArrow_1 i 1 u 1:2 #StyleArrow lc "red" ,\
BentArrow_1 i 2 u 1:2:3:4 #StyleHead as 1 ,\
BentArrow_2 i 0 u 1:(CP($2)) #CtrlPoints ,\
BentArrow_2 i 1 u 1:2 #StyleArrow lc "web-green" ,\
BentArrow_2 i 2 u 1:2:3:4 #StyleHead as 2 ,\
BentArrow_3 i 0 u 1:(CP($2)) #CtrlPoints ,\
BentArrow_3 i 1 u 1:2 #StyleArrow lc "blue" ,\
BentArrow_3 i 2 u 1:2:3:4 #StyleHead as 3
The BentArrow.fct file contain:
# Implements a bent arrow using Cubic Bézier curves (https://en.wikipedia.org/wiki/Bézier_curve)
#
# Usage: call 'BentArrow.fct' tag xi yi yc1 yc1 xc2 yc2 xf yf
# where
# xi,yi = start point
# xc1,yc1 = control point #1
# xc2,yc2 = control point #2
# xf,yf = final point
#
# The algorithm creates
# 1) a variable named BentArrow_id with 'id' as a integer number,
# defined by user like a standart arrow, and
# 2) a datafile (e.g BentArrow_id.bentarrow) containing
# i) the control points,
# ii) the datapoints to create the curve, and
# iii) the datapoints do ceate head
# as indexable datablocks (0, 1 and 2, respectively).
# The number of datapoint (samples) used on bent arrow construction
# are defined by 'ArrowPoints' (default 50)
# Receiving the arguments from 'call' command
tag = int(ARG1)
x_i = real(ARG2)
y_i = real(ARG3)
x_1 = real(ARG4)
y_1 = real(ARG5)
x_2 = real(ARG6)
y_2 = real(ARG7)
x_f = real(ARG8)
y_f = real(ARG9)
# Defining the variable to filename, based on 'tag', and creating the datafile
eval sprintf( "%s_%g = %s", 'BentArrow', tag, sprintf("'BentArrow_%g.bentarrow'", tag) )
# Checking if 'ArrowPoints' is defined
if ( !exists("ArrowPoints") ) {
ArrowPoints = 50
}
# Quadratic Bézier function
DrawArrow(t,p0,p1,p2,p3) = (1-t)**3*p0 + 3*(1-t)**2*t*p1 + 3*(1-t)*t**2*p2 + t**3*p3 # 0 <= t <= 1
# Creating the datafile containing the datapoints to bent arrow
set print sprintf('BentArrow_%g.bentarrow', tag)
# ----- ControlPoints -----------------------
print "# Block index 0 (control points)"
print sprintf("% e\t% e", x_i, y_i)
print sprintf("% e\t% e", x_1, y_1)
print ""
print sprintf("% e\t% e", x_2, y_2)
print sprintf("% e\t% e", x_f, y_f)
print ""
print ""
# ----- ArrowData -----------------------
print "# Block index 1 (arrow)"
do for [i=0:int(ArrowPoints):1] {
t = i/real(ArrowPoints)
print sprintf("% e\t% e", DrawArrow(t,x_i,x_1,x_2,x_f), DrawArrow(t,y_i,y_1,y_2,y_f))
}
print ""
print ""
# ----- ArrowHead -----------------------
print "# Block index 2 (head)"
do for [i=int(ArrowPoints)-1:int(ArrowPoints):1] {
t = i/real(ArrowPoints)
x_head = x_f - DrawArrow(t,x_i,x_1,x_2,x_f)
y_head = y_f - DrawArrow(t,y_i,y_1,y_2,y_f)
print sprintf("% e\t% e\t% e\t% e", DrawArrow(t,x_i,x_1,x_2,x_f), DrawArrow(t,y_i,y_1,y_2,y_f), x_head, y_head)
}
unset print
Improvements will be well received!

Gnuplot - cannot change colors of bars

Given dataset:
0 t1 0.52
1 t2 0.66
2 t3 0.58
3 t4 0.57
4 t5 0.68
5 t6 0.61
6 t7 0.55
7 t8 0.52
8 t9 0.58
9 t10 0.50
10 t11 0.59
I cannot manage to get the colors of the bars to change. What I'm trying below is to color green the highest score which happens on line 4. Please have a look over the below:
set terminal postscript eps enhanced 20
set output "edscore2_joint.eps"
set style line 1 lc rgb "#5F9EA0"
set style line 2 lc rgb "#DC143C"
set style line 3 lc rgb "green"
set yrange [0:1]
set ylabel "ed_{score}"
set xlabel "Technique"
set style fill solid
set boxwidth 0.5
set xtics rotate by -45
plot "edscore2_joint.dat" using 1:3:xtic(2) with boxes ls 1 fillstyle pattern 1 notitle ,\
"edscore2_joint.dat" every ::4::4 using 1:3:xtic(2) with boxes ls 3 fillstyle pattern 2 notitle ,\
"edscore2_joint.dat" using 1:($3+0.05):3 with labels notitle
The terminal postscript is monochrome by default. Use either the option color, or, if you have a recent enough gnuplot version, use the terminal epscairo.

How to highlight regions of plot with gnuplot

I'd appreciate if somebody can help with this question.
I am working with a radar (or spiderweb) plot with gnuplot 5.0.0:
The scale and range in all axes is the same. The numbers at and beyond 1 have a special meaning and I would like to highlight that.
I am thinking of three things that would increase visibility:
Simply make the tick mark at 1 (labelled "Limit") boldfaced. How could I highlight just a specific tick and label?
I could also highlight the circular dashed line at level 1
On the plot itself I'd like to have the background colored differently for radius > 1.
How can I achieve either of the three options above? All three would be ideal of course, but just a a minimum differentiation from the rest of that value would help.
This is what generated the plot in the link:
set term x11
set title "My title "
set polar
set angles degrees
npoints = 6
a1 = 360/npoints*1
a2 = 360/npoints*2
a3 = 360/npoints*3
a4 = 360/npoints*4
a5 = 360/npoints*5
a6 = 360/npoints*6
set grid polar 360
set size square
set style data lines
unset border
set grid ls 0
set linetype 1 lc rgb 'red' lw 2 pt 7 ps 2
M=2.2
set arrow from 0,0 to first M*cos(a1), M*sin(a1)
set arrow from 0,0 to first M*cos(a2), M*sin(a2)
set arrow from 0,0 to first M*cos(a3), M*sin(a3)
set arrow from 0,0 to first M*cos(a4), M*sin(a4)
set arrow from 0,0 to first M*cos(a5), M*sin(a5)
set arrow from 0,0 to first M*cos(a6), M*sin(a6)
a1_min = 0
a1_max = 1
a2_min = 0
a2_max = 1
a3_min = 0
a3_max = 1
a4_min = 0
a4_max = 1
a5_min = 0
a5_max = 1
a6_min = 0
a6_max = 1
set label "M1" at M*cos(a1),M*sin(a1) center offset char 1,1
set label "M2" at M*cos(a2),M*sin(a2) center offset char 1,1
set label "M3" at M*cos(a3),M*sin(a3) center offset char 1,1
set label "M4" at M*cos(a4),M*sin(a4) center offset char 1,1
set label "M5" at M*cos(a5),M*sin(a5) center offset char 1,1
set label "M6" at M*cos(a6),M*sin(a6) center offset char 1,1
set xrange [0:1]
set yrange [0:1]
set xtics axis 0,0.5,M
unset ytics
set rrange [0:M]
set rtics (""0,""0.25,""0.5,""0.75,"Limit"1,""1.25,""1.50,""1.75,""2)
set rtics scale 0 format ''
set style fill transparent solid 0.5
set style function filledcurves y1=0.5
set grid noxtics nomxtics noytics nomytics front
plot '-' u ($1==1?a1:($1==2?a2:($1==3?a3:($1==4?a4:($1==5?a5:($1==6?a6:$1)))))):($1==1?(($2-a1_min)/(a1_max-a1_min)):($1==2?(($2-a2_min)/(a2_max-a2_min)):($1==3?(($2-a3_min)/(a3_max-a3_min)):($1==4?(($2-a4_min)/(a4_max-a4_min)):($1==5?(($2-a5_min)/(a5_max-a5_min)):($1==6?(($2-a6_min)/(a6_max-a6_min)):$1)))))) w filledcurve lt 1 title "AAA",\
'-' u ($1==1?a1:($1==2?a2:($1==3?a3:($1==4?a4:($1==5?a5:($1==6?a6:$1)))))):($1==1?(($2-a1_min)/(a1_max-a1_min)):($1==2?(($2-a2_min)/(a2_max-a2_min)):($1==3?(($2-a3_min)/(a3_max-a3_min)):($1==4?(($2-a4_min)/(a4_max-a4_min)):($1==5?(($2-a5_min)/(a5_max-a5_min)):($1==6?(($2-a6_min)/(a6_max-a6_min)):$1)))))) w filledcurve lt 2 title "BBB"
1 2.1
2 1
3 0.1
4 0.5
5 0.5
6 0.1
1 2.1
EOF
1 2.2
2 0.9
3 0.9
4 0.2
5 0.3
6 0.1
1 2.2
EOF
set output
I've taken the liberty to streamline your script a bit, you can now easily adjust the number of arms in the web. Also added a coloured background for 1 >r > M.
Btw., there is no need to enter the first datapoint again at the end to close the contour.
Update: That is, there shouldn't be. However the line between the last and first point is missing then, even with giving the "closed" option to "with filledcurve". I wonder if this is a bug.
set term wxt
set title "My title "
set polar
set angles degrees
set grid polar 360
set size square
set style data lines
set key top left
unset border
set grid ls 0
set linetype 1 lc rgb 'red' lw 2 pt 7 ps 2
M=2.2
npoints = 7
minima = "0 0 0 0 0 0 0" # adjust and add more as necessary
maxima = "1 1 1 1 1 1 1"
a(n) = 360./npoints*n
amin(n) = 0.0 + word(minima,int(n))
amax(n) = 0.0 + word(maxima,int(n))
do for [i=1:npoints] {
set arrow i from 0,0 to first M*cos(a(i)), M*sin(a(i))
set label i sprintf("M%.f",i) at M*cos(a(i)),M*sin(a(i)) \
center offset char 1,1
}
set object 1 circle at 0,0 size M fillc rgb "yellow" behind
set object 2 circle at 0,0 size 1 fillc rgb "white" behind
set xrange [0:1]
set yrange [0:1]
set xtics axis 0,0.5,M
unset ytics
set rrange [0:M]
set rtics (""0,""0.25,""0.5,""0.75,"{/:Bold Limit}"1,""1.25,""1.50,""1.75,""2)
set rtics scale 0 format ''
set style fill transparent solid 0.5
set style function filledcurves y1=0.5
set grid noxtics nomxtics noytics nomytics front
plot '-' us (a($1)):(($2-amin($1))/(amax($1)-amin($1))) \
w filledcurve closed lt 1 title "AAA",\
'-' us (a($1)):(($2-amin($1))/(amax($1)-amin($1))) \
w filledcurve closed lt 2 title "BBB"
1 2.1
2 1
3 0.1
4 0.5
5 0.5
6 0.1
7 0.5
EOF
1 2.2
2 0.9
3 0.9
4 0.2
5 0.3
6 0.1
7 1.8
EOF

Gnuplot different colors

I'm trying to color a plot and a fit in gnuplot in different colors, but it doesn't work:
set ylabel "s in m"
set xlabel "t in s"
unset key
set style line 1 lt 2 lc rgb "red" lw 3
set style line 2 lt 2 lc rgb "orange" lw 2
plot "-" with lines ls1
0 0
1 4.2
2 7.9
3 11.7
4 16.3
fit "-" with lines ls2
0 0
1 4.2
2 7.9
3 11.7
4 16.3
Does anybody have an idea what I am doing wrong?
There are several things you are doing wrong:
The fit command is a bit different from the plot command. You must define a function like f(x) = a*x + b and fit this to your data. This calculates appropriate values for a and b. Afterwards you can plot the function.
You must terminate the inline data with an e.
To select a line style, use ls 1 (with the space before the number).
So your script should look as follows:
set ylabel "s in m"
set xlabel "t in s"
unset key
set style line 1 lt 2 lc rgb "red" lw 3
set style line 2 lt 2 lc rgb "orange" lw 2
f(x) = a*x + b
fit f(x) '-' via a,b
0 0
1 4.2
2 7.9
3 11.7
4 16.3
e
plot f(x) with lines ls 2, "-" with points ls 1
0 0
1 4.2
2 7.9
3 11.7
4 16.3
e
This plots your fit as a line, and the according data as points.

Resources