Gnuplot histogram with plot line - gnuplot

I am using Gnuplot to create a histogram with a plot line, however, the plot line is not fit well with bar head, also I would like to put the line a little bit far from the bar head.
set border 3
set boxwidth 0.9
set tics nomirror out scale 0.75
set style fill solid 0.8
plot "03.txt" using 2:xtic(1) lt rgb "#0060ad" notitle, "" using 2 smooth csplines notitle with lines ls 1, "" using 3 lt rgb "#ff6600" notitle, "" using 3 smooth csplines notitle with lines ls 2, "" using 4 lt rgb "#dd181f" notitle, "" using 4 smooth csplines notitle with lines ls 3
Updated:
This is the data file:
500000 25.938 25.938 2
1000000 52.385 52.385 4
1500000 79.749 78.405 6.125
2000000 152.589 100.261 12.479
2500000 224.869 118.364 19.159

This should work for any number of columns, you have to specify them in the variable N, and number them in calls to custom function xbox. This should do for a non-intensive usage. You can offset vertically the curves with the OFFSET variable (in units of y axis)
set border 3
#number of columns to be plotted
N=3
#vertical offset
OFFSET=0
#gapwidth (set to gnuplot's default)
GW=2
xbox(x,i)=x+(i-N*0.5)/(N+GW)
set boxwidth 0.9
set tics nomirror out scale 0.75
set style fill solid 0.8
plot "03.txt" using 2:xtic(1) lt rgb "0060ad" notitle, \
"" using 2 with histogram notitle, \
"" using (xbox($0,1)):($2+OFFSET) smooth csplines notitle with lines ls 1, \
"" using 3 lt rgb "#ff6600" notitle with histogram, \
"" using (xbox($0,2)):($3+OFFSET) smooth csplines notitle with lines ls 2, \
"" using 4 lt rgb "#dd181f" notitle with histogram, \
"" using (xbox($0,3)):($4+OFFSET) smooth csplines notitle with lines ls 3

Related

How do I add more space using gnuplot yerrorbars when I have a lot of data on my chart?

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"

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:

How to make key colour black in Gnuplot

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

Same Gnuplot linestyle as in graph in key/legend

I would like to plot a legend/key, which shows the different symbols on the line. Currently my plots look like this:
Unfortunately the symbols (triangle, rectangle and circle) are not shown in the key/legend. How is it possible to add them?
I use the following gnuplot script:
set title tit font "palatino,20"
set xlabel xlbl font "palatino,20"
set ylabel ylbl font "palatino,20"
#set logscale x
set output graphfilename.".pdf"
set terminal pdf
set border linewidth 2
set style line 1 lc rgb '#0060ad' lt 1 lw 2 pt 5 # --- blue
set style line 2 lc rgb '#00ad60' lt 1 lw 2 pt 7 # red .
set style line 3 lc rgb '#ad0000' lt 1 lw 2 pt 9 # green .
set tics scale 0.8
set key below
plot file1 using ($1/1000):($2/1000000):($3/1000000):($4/1000000) notitle w yerrorbars ls 1, \
'' using ($1/1000):($2/1000000) title "Hlog" w lines ls 1,\
file2 using ($1/1000):($2/1000000):($3/1000000):($4/1000000) notitle w yerrorbars ls 2, \
'' using ($1/1000):($2/1000000) title "Iris" w lines ls 2,\
file3 using ($1/1000):($2/1000000):($3/1000000):($4/1000000) notitle w yerrorbars ls 3, \
'' using ($1/1000):($2/1000000) title "Java" w lines ls 3
Generally, you can get both lines and points, if you plot with the linespoints plotting style:
sc(x) = x*1e-6
plot file1 using ($1/1000):(sc($2)):(sc($3)):(sc($4)) notitle w yerrorbars ls 1 ps 0.5, \
'' using ($1/1000):(sc($2)) title "Hlog" w linespoints ls 1
That draws the points twice, which shouldn't be a problem unless you use transparency. I also shrinked the points which are drawn together with the errorbars to 50%, so you don't get problems with antialiasing.
As another option you could add the title only the the errorbars, in which case the legend would look like |---x---| (i.e. contain also the errorbars):
sc(x) = x*1e-6
plot file1 using ($1/1000):(sc($2)):(sc($3)):(sc($4)) title "Hlog" w yerrorbars ls 1, \
'' using ($1/1000):(sc($2)) notitle w lines ls 1

Thicker lines in the legend of gnuplot

I'm plotting some data curves with gnuplot, and they look like this:
However, the line samples in the legend are too thin. When you have more curves, it becomes hard to distinguish the colors. You can increase the thickness of the curves using "linewidth", e.g., by adding "lw 3" to the plot command, and you'd get this:
However, this increases the thickness everywhere. Is it possible to make the lines thick in the legend only? I know it can be done "the other way", by postprocessing on the output .png file. But is there a direct approach, using some gnuplot setting/wizardry?
Unfortunately, I don't know a way to control the thickness of the lines in the key, since they correspond to the lines being drawn. You can see what you can change by typing help set key in gnuplot.
Using multiplot, you can draw the plot lines first without the key, then draw the key again for 'ghost lines'. Here is a code sample which would do that:
set terminal png color size 800,600
set output 'plot.png'
set multiplot
unset key
plot '../batteries/9v/carrefour.txt' w lp, \
'../batteries/9v/philips.txt' w lp, \
'../batteries/9v/sony.txt' w lp
set key; unset tics; unset border; unset xlabel; unset ylabel
plot [][0:1] 2 title 'Carrefour' lw 4, \
2 title 'Philips' lw 4, \
2 title 'Sony' lw 4
In the second plot command, the function 2 (a constant) is being plotted with a y range of 0 to 1, so it doesn't show up.
I ran across this post and it gave me a critical idea.
The provided solution does not work in multiplot mode, since the second plot command will trigger the second plot, which is most likely not desired.
as a workaround one can set the original data as "notitle", then plot data outside of range with the same linetype and color in different thickness with the desired title. I'll just leave my current example here. It also includes linestyles that i have declared. So i just use the same linestyle (ls) to get the same color but change the thickness on the second line.
# for pngs
set terminal pngcairo size 1600,600 font ',18' enhanced
set output "pic_multi_kenngr_ana.png
set style line 2 lc rgb '#0ce90b' lt 1 lw 1.5 # --- green
set style line 3 lc rgb '#09e0b3' lt 1 lw 1.5 # .
set style line 4 lc rgb '#065fd8' lt 1 lw 1.5 # .
set style line 5 lc rgb '#4e04cf' lt 1 lw 1.5 # .
set style line 6 lc rgb '#c702a9' lt 1 lw 1.5 # .
set style line 7 lc rgb '#bf000a' lt 1 lw 1.5 # --- red
set multiplot layout 1,2
set xtics rotate
set tmargin 5
set xtics 12
set grid xtics
# set axis labels
set ylabel 'T [K]'
set xlabel 'Zeit [h]'
# select range
set xrange [0:48]
set yrange [290.15:306.15]
set title "(a) Bodentemperatur"
set key top right Right
plot 'par_crank_hom01lvls.04.dat' u 1:3 with lines ls 7 notitle,\
'par_crank_str01lvls.16.dat' u 1:3 with lines ls 2 notitle,\
500 t 'z = 4 cm' ls 7 lw 4,\
500 t 'z = 16 cm' ls 2 lw 4
################################################
set title "(b) Bodenwärmestrom an der Oberfläche"
set ylabel 'G [W m^{-2}]'
set yrange[-110:110]
unset key
plot 'par_crank_str01_ghf.dat' u 1:3 with lines
unset multiplot
I hope this will help someone
An even more simple work-around (imho) is to define the colours explicitly and plot each line twice, once with high lw for the key and also with the title to appear in the key, but adding "every ::0::0" which effectively ends up in plotting nothing, and once the normal way. See the following code snippet:
plot data u 0:1 w l linecolor rgb #1b9e77 lw 2 t "",\
data every ::0::0 u 0:1 w l linecolor rgb #1b9e77 lw 4 t "Title"
To expand on the NaN comment by #Svalorzen, the following will graph two lines of width 1 from some datafile.txt with no titles and create matching blank lines with the specified titles and width 5 for the key only:
plot [][]\
NaN title "Title1" w line lt 1 lc 1 lw 5,\
NaN title "Title2" w line lt 1 lc 2 lw 5,\
"datafile.txt" using 1:2 title "" w line lt 1 lc 1 lw 1,\
"datafile.txt" using 1:3 title "" w line lt 1 lc 2 lw 1
I find an answer for this:
Set key linewidth
in your case, must be:
plot '../batteries/9v/carrefour.txt' w l lw 1 linetype 1 notitle, 0/0 linetype 1 linewidth 5 title 'Carrefour'
rep '../batteries/9v/philips.txt' w l lw 1 linetype 2 notitle, 0/0 linetype 2 linewidth 5 title 'Philips'
rep '../batteries/9v/sony.txt' w l lw 1, linetype 3 notitle, 0/0 linetype 3 linewidth 5 title 'Sony'
Try something like:
plot # ... \
keyentry w l lw 1 lc 2 t "Title" # ...
And remove the old keys.

Resources