I have file “data.txt” containing three columns. Column 1 is for x axis. I want to draw smooth curves corresponding to data points of column 2 and 3 and then want to fill colour between these two lines.
File content is;
10 -1.3 1.1
20 -0.956 0.933
50 -0.761 0.684
80 -0.523 0.439
110 -0.227 0.20
130 -0.07 0.06
My script lines are,
plot “data.txt” u 1:2 smooth bezier w filledcurves above,\
“data.txt” u 1:3 smooth bezier w filledcurves below
But I’m not getting desired shaded plot.
I guess you have two challenges here:
you cannot smooth and fill at the same time
you can only fill between two columns of the same dataset or file
One possible way would be the following:
plot the data smooth bezier into a table $Smooth
N is the number of lines the combined smoothed data $Smooth
merge these smoothed data by using line 1 and 1+N/2, line 2 and 2+N/2, etc. into a dataset $Paste
for the fill you then have to use columns 1, 2 and 5
Script:
### fill area between smoothed curves
reset session
$Data <<EOD
0 0 90
10 10 50
50 20 40
80 50 60
100 30 50
EOD
set table $Smooth
set samples 20
plot $Data u 1:2 smooth bezier
plot $Data u 1:3 smooth bezier
unset table
set print $Paste
N = |$Smooth|
do for [i=1:N/2] {
print $Smooth[i].$Smooth[i+N/2]
}
set print
plot $Data u 1:2:3 w filledcurves lc rgb 0xcc0000ff ti "fill between data", \
'' u 1:2 w lp pt 7 lc "red" ti "original data", \
'' u 1:3 w lp pt 7 lc "red" notitle, \
$Smooth u 1:2 w lp pt 7 lc "green" ti "smoothed curves", \
$Paste u 1:2:5 w filledcurves lc rgb 0xccff0000 ti "fill between smoothed"
### end of script
Result:
For future reference, the development version of gnuplot (5.5) greatly extends the options for smoothing. For your case the obvious command works as expected. The only caveat is that for open curves (endpoints are not equal) you must use smooth sbezier rather than smooth bezier.
$DATA << EOD
10 -1.3 1.1
20 -0.956 0.933
50 -0.761 0.684
80 -0.523 0.439
110 -0.227 0.20
130 -0.07 0.06
EOD
set xrange noextend
set style fill transparent solid 0.25
plot $DATA using 1:2:3 smooth sbezier with filledcurves between, \
'' using 1:2 with lp, '' using 1:3 with lp
As far as I understand, above and below expect three column input, and this does not work with smooth.
But starting from this and this answer, you can try something like the following:
set xzeroaxis
set tics front
plot "data.txt" u 1:3 smooth bezier notitle w filledcurves x1 lc rgb "#b0ffff00", \
"data.txt" u 1:2 smooth bezier notitle w filledcurves x1 lc rgb "#00ffffff", \
"data.txt" u 1:3 smooth bezier lt 1, \
"data.txt" u 1:2 smooth bezier lt 2
Both filledcurves plots reach from the curve to the x-axis, the second one in white covers the first one in yellow leaving the space between the two curves in yellow.
See help lc or help linecolor for color details.
This is the result:
Related
I've installed gnuplot 5.5 from git. Now it doesn't plot with automatic axis limits.
Here is the graph produced with earlier version (5.3 or 5.4):
And this is plotted with current version:
Here is the command for this plot:
plot [][3.0145:3.5755] 3.04 w filledcurves x1 fc rgb "#d9d9d9" notitle, \
3.55 w filledcurves x2 fc rgb "#d9d9d9" notitle, \
for [i=1:11] 'gpdata.dat' every :::0::0 using 1:i+1 lt i+1 lw 3 ps 1.5 t word(elements,i) w linesp,\
3.04 w lines lw 4 lt 1 lc rgb "red" t 'Допуск',3.55 w lines lw 4 lt 1 lc rgb "red" notitle
When I set the limits explicitly: plot [:35064.46][3.0145:3.5755] I get this:
i.e. the end points are hidden.
Is there a way to return previous behavior?
According to the StackOverflow "rules": no answer in the comments...
set xrange[:] noextend
should avoid the extension of the plotting range to the next "nice" tic. Check help noextend.
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:
I added the yerrorbars keyword to show the standard deviation on my chart but because I have a lot of data the plot is not very clear and the std deviation as well. I would like to add more spaces when showing the standard deviation in the same way that is added on the line style using pi : set style line 4 lc rgb '#000000' lt 3 lw 1.5 ps 0.5 pt 3 pi 15. How would I do that?
set label 1 "(a) workload: 50K r/s\npre-agg 77K tuples" at "300",6.5 font "{,10}"
plot t=0 "throughput-vs-latency-50K-8combiners-8reducers-all.csv" u (t==0?(t0=timecolumn(1,myTimeFmt),t=1):NaN, timecolumn(1,myTimeFmt)-t0):(column(2)/1000):(column(3)/1000) skip 2 notitle with linespoints ls 1 axis x1y1 \
, t=0 "throughput-vs-latency-50K-8combiners-8reducers-all.csv" u (t==0?(t0=timecolumn(1,myTimeFmt),t=1):NaN, timecolumn(1,myTimeFmt)-t0):(column(4)/1000) skip 2 notitle with linespoints ls 2 axis x1y1 \
, t=0 "throughput-vs-latency-50K-8combiners-8reducers-all.csv" u (t==0?(t0=timecolumn(1,myTimeFmt),t=1):NaN, timecolumn(1,myTimeFmt)-t0):(column(6)/1000) skip 2 notitle with linespoints ls 3 axis x1y2 \
, t=0 "throughput-vs-latency-50K-8combiners-8reducers-all.csv" u (t==0?(t0=timecolumn(1,myTimeFmt),t=1):NaN, timecolumn(1,myTimeFmt)-t0):(column(8)/1000):(column(9)/1000) skip 2 notitle with yerrorbars ls 4 axis x1y2 \
I think you would have to split the curve for that data into two parts.
The first part would draw the lines and points for every point in the data set;
the second part would draw errorbars only for every Nth point. The keyword needed is every N.
set errorbars lt -1
plot $DATA using 1:2 with linespoints lt 3 notitle, \
$DATA every 5 using 1:2:3 with yerrorbars lt 3 title "DATA"
Another suggestion: instead of crowded errorbars, why not an "error-shade"?
Code:
### shaded area as error "bar"
reset session
# create some test data
set table $Data
plot '+' u 1:(sin($1)):(rand(0)+0.25) w table
unset table
set key invert
plot $Data u 1:($2-$3):($2+$3) with filledcurves lc rgb "light-grey" ti "Error", \
'' u 1:2 w lp ti "Data"
### end of code#
Result:
For many data points with errorbars, consider set bar 0, error bars in the background, and/or transparency. Also point size can be reduced.
set samp 2000
set table $Data
plot '+' u 1:(sin($1)+(rand(0)+0.25)):(rand(0)+0.25) w table
unset table
set bar 0
plot $Data with err lc rgb "grey" ti "Error", \
'' u 1:2 w p lc "black" pt 6 ti "Data"
I know how to use filledcurve with using 1:2:3 to fill the area between the curves described by columns 2 and 3.
I also know how to smooth a single curve using acsplines with using 1:2:(0.1) (with 0.1 being the smoothing weight for each point).
But I fail to combine the two, i.e. fill the area between two smoothed curves. All variants I try give me error messages like duplicated or contradicting arguments in datafile options.
This is what I tried:
plot 'datafile' using 1:2:3:(0.1):(0.1) smooth acs with lines
plot 'datafile' using 1:2:(0.1):3:(0.1) smooth acs with lines
Is this combination possible at all? How is the syntax then?
I guess you can't combine smooth acspline and with filledcurves, but I also don't know why this shouldn't be possible.
Well, as a workaround, plot your smooth acspline curve into a data table first and then plot it with filledcurves.
Code:
### filled acspline curve
reset session
$Data <<EOD
1 2
2 4
3 3
4 1
EOD
# plot your acspline data into a table
set table $ACSpline
plot $Data u 1:2 smooth acspline
unset table
set style fill transparent solid 0.1
plot $Data u 1:2 w lp pt 7 lc rgb "black" ti "Original data", \
$Data u 1:2 smooth acspline lw 2 lc rgb "red" ti "acspline", \
$ACSpline u 1:2 w filledcurves x1 lc rgb "red" ti "acspline filled"
### end of code
Result:
Addition:
There is another way to get data into a table. Check help set print.
With this, you can get the data of the two splines into one datablock and can plot the area between them. Maybe someone knows a simpler way to achieve this.
Code:
### filled curve between two acsplines
reset session
$Data <<EOD
1 2 4
2 4 1
3 3 0
4 1 3
EOD
# plot your acspline data into tables
set table $ACSpline1
plot $Data u 1:2:(1) smooth acspline
unset table
set table $ACSpline2
plot $Data u 1:3:(1) smooth acspline
unset table
set print $BetweenSplines
do for [i=1:|$ACSpline1|] {
print sprintf("%s %s %s",word($ACSpline1[i],1),word($ACSpline1[i],2),word($ACSpline2[i],2))
}
set print
set style fill transparent solid 0.5
plot $Data u 1:2 w lp pt 7 lc rgb "black" ti "Original data col 2", \
$Data u 1:3 w lp pt 7 lc rgb "blue" ti "Original data col 3", \
$ACSpline1 u 1:2 w l lw 2 lc rgb "red" ti "acspline col 2", \
$ACSpline2 u 1:2 w l lw 2 lc rgb "green" ti "acspline col 3", \
$BetweenSplines u 1:2:3 w filledcurves lc rgb "yellow" ti "acspline filled"
### end of code
Result:
How can I make the key "symbols" black in colour when using palettes?
I think you cannot control this directly, here a workaround:
plot 'MOD1.dat' u 2:3:1 w p pt 7 ps 2 lt black, \
'MOD1.dat' u 2:3:1 w p pt 7 ps 2 lt palette notitle
So, we first plot the data without legend in black, then plot the data points but no legend. The nice thing about this approach is that there is no need to fix the x or y range.
I would just create a dummy line and use notitle on the real lines. Something like
set yrange[0:1]
plot "realdata1.data" u 1:2 w linespoints lt 1 notitle , \
"realdata2.data" u 1:2 w linespoints lt 2 notitle , \
1/0 w linespoints lt 1 lc rgb 'black' title 'Model1', \
1/0 w linespoints lt 1 lc rgb 'black' title 'Model2'
Then replace lt 1 with whatever you have used for style in your current plot. Note that you'll need to use set yrange for gnuplot to accept the dummy curve