How can I offset boxes to match steps? - gnuplot

My application deploys to CentOS 6 and CentOS 7. I have just found out that Gnuplot 4.4 (which is the latest I can use on CentOS 6, for logistical reasons) does not support fillsteps, so my lovely graphs are not rendering there.
Said graphs have a series of steps for a bounding line, and a series of fillsteps to create a solid colour. (I'm also faking a stacked plot, but never mind that.)
I reckon I can use steps and boxes instead, but boxes are offset on the axis by half a tic. Can I shuffle them over in an efficient and expressive way? Or perhaps I should be coming at this completely differently?
Original code
set terminal pngcairo enhanced font ",10" size 576, 231
set border back
set grid
set xzeroaxis lt -1
set style line 1 lc rgbcolor "#4E9EF3"
set style line 2 lc rgbcolor "#B23F3F"
set timefmt "%s"
set xdata time
set xlabel "Time (+00:00)"
set format x "%H:%M"
set offset graph 0, graph 0, graph 0.05, graph 0.05
set xrange [571795200:571881600]
set yrange [0:]
plot 'data.csv' using 1:($2+$3) with fillsteps ls 1 fs solid 0.3 noborder notitle,
'' using 1:($2+$3) with steps ls 1 notitle,
'' using 1:2 with fillsteps ls 2 fs solid 0.3 noborder notitle,
'' using 1:2 with steps ls 2 notitle
Attempt at replacing fillsteps with boxes
set terminal pngcairo enhanced font ",10" size 576, 231
set border back
set grid
set xzeroaxis lt -1
set style line 1 lc rgbcolor "#4E9EF3"
set style line 2 lc rgbcolor "#B23F3F"
set boxwidth 1.0 relative
set timefmt "%s"
set xdata time
set xlabel "Time (+00:00)"
set format x "%H:%M"
set offset graph 0, graph 0, graph 0.05, graph 0.05
set xrange [571795200:571881600]
set yrange [0:]
plot 'data.csv' using 1:($2+$3) with boxes ls 1 fs solid 0.3 noborder notitle,
'' using 1:($2+$3) with steps ls 1 notitle,
'' using 1:2 with boxes ls 2 fs solid 0.3 noborder notitle,
'' using 1:2 with steps ls 2 notitle

My input data happens to be evenly spaced, with the X axis increment known to the calling code.
So, instead of:
plot 'data.csv' using 1:2 with fillsteps ls 2 fs solid 0.3 noborder notitle
I can do:
# (for example)
barwidth = 900
set boxwidth 1.0 relative
plot 'data.csv' using ($1+barwidth/2.0):2 with boxes ls 2 fs solid 0.3 noborder notitle
… and this appears to provide consistent results.

Related

Set background of boxes in boxplot to a specific color with gnuplot

I've got the following data:
# id min 1st quart median 3rd quart max sum std-dev name
1 0.00029 0.02590 0.06331 0.12910 6.50177 1524.58705 0.13483 spec
2 1.50041 1.59762 1.67226 1.79827 13.45151 26583.69935 0.48373 schema
3 0.00206 0.01292 0.02505 0.09679 116.93156 5337.36854 2.06006 truss
And the following gnuplot script:
set terminal png enhanced background rgb 'white' size 1920,1200 font "Verdana 10"
set output "charts/summary.png"
set boxwidth 0.2 absolute
set title "Validating all data"
set xrange[0:4]
set yrange[0.00005:50]
set logscale y
set grid y
set tics scale 0
set xtics rotate by -45
set xtics nomirror
set ytics nomirror
set border 2
set style fill solid 0.25 border -1
set style data boxplot
plot "data/summary" using 1:3:2:6:5:(0.6):xticlabels(9) with candlesticks title 'Quartiles' whiskerbars, \
'' using 1:4:4:4:4:(0.6) with candlesticks lt -1 notitle
The output of which looks like:
The problem being that I can't figure out how to set the background color of the boxes in the boxplot. I can only seem to turn on and off the fill-in color by removing the set style fill solid 0.25 border -1 line.
Although the name of keyword doesn't suggest so, the linecolor seems to affect the color of the boxes, thus for example:
plot "data/summary" using 1:3:2:6:5:(0.6):xticlabels(9) with candlesticks lc rgb 'blue' title 'Quartiles' whiskerbars, \
'' using 1:4:4:4:4:(0.6) with candlesticks lt -1 notitle

How to draw a histogram with broken x-axis and string labels?

I am trying to draw a histogram with broken x-axis. I learnt the basic solution from this post.
However, the x-axis of my histogram is based on strings, not number. It's like this:
set terminal pdf
set output "test-bar.pdf"
set boxwidth 1.0 absolute
set style fill solid 1 border 0
set datafile separator ','
set style data histograms
set xtics nomirror rotate by -45
set ylabel 'Normalized Overhead (%)'
set grid ytics
set yrange [0:10]
plot 'test-bar.csv' using 2:xtic(1) lc rgb "#1E90FF" title ''
And the data is listed like this:
expand , 8.63390441828
cut , 6.84657194596
sync , 6.03615235627
fold , 4.22117995557
nl , 3.54228486647
truncate , 2.66222961714
tr , 2.38357169059
stty , 2.28166797757
users , 2.04211869831
factor , 1.81517270821
tac , 1.790947574
uniq , 1.78799489138
mv , 1.75054704603
mktemp , 1.72228202368
dircolors , 1.6974169738
Right now the plot is in this way:
If I want to leverage the broken axis feature, say, insert the broken between stty and users, how can I do that?
Am I clear enough? Thanks.
Although you use xtic labels from your data file, the xtics are placed at integer x-values, starting at 0. Now, you cannot directly set arbitrary x-values when plotting histograms. You must use newhistogram at ... to shift the second part of the histogram further to the right:
split = 8
plot 'test-bar.csv' using 2:xtic(1) every ::0::(split-1) lt 1,\
newhistogram at split+1,\
'' using 2:xtic(1) every ::split lt 1
Drawing of the upper and lower borders as well as the broken axis signs is done as shown in the post you linked. A possible full script could be
set terminal pdf
set output "test-bar.pdf"
set boxwidth 0.5 absolute
set style fill solid 1 border 0
set datafile separator ','
set style data histograms
set style histogram rowstacked
set xtics nomirror rotate by -45
set ylabel 'Normalized Overhead (%)'
set grid ytics
set yrange [0:10]
unset key
set border 2+8
set linetype 1 lc rgb "#1E90FF"
split=8
dx = 0.125
dy = 0.03
do for [i=0:1] {
set arrow 1+i from graph 0,graph i to first split-dx,graph i lt -1 nohead
set arrow 3+i from first split+dx,graph i to graph 1,graph i lt -1 nohead
set arrow 5+i from first split-2*dx,graph i-dy to first split,graph i+dy lt -1 nohead
set arrow 7+i from first split,graph i-dy to split+2*dx,graph i+dy lt -1 nohead
}
plot 'test-bar.csv' using 2:xtic(1) every ::0::(split-1) lt 1,\
newhistogram at split+1,\
'' using 2:xtic(1) every ::split lt 1
Alternatively, if you don't add or stack more columns, you could use the boxes plotting style, which allows you to use a normal numerical axis.

Plot boolean values on a time based line graph

I am plotting a time based line graph and would like to add a boolean data series to it.
Is it possible to have the boolean data highlight the full height of the canvas of the graph where the value is true?
Plotfile:
set datafile separator ","
set terminal pngcairo size 800,400
set title "Solar charge monitor"
set yrange [0:]
set ylabel "V"
set y2range [0:]
set y2label "A"
set y2tics
set xlabel "Date"
set xdata time
set timefmt "%Y-%m-%dT%H:%M:%SZ"
set key left top
set grid
set output "samplePlot.png"
plot "sampleData.csv" using 1:2 with lines lw 2 title 'Batt (V)', \
"sampleData.csv" using 1:3 with lines lw 2 title 'Solar (V)', \
"sampleData.csv" using 1:4 with lines lw 2 title 'Charge (A)' axes x1y2, \
"sampleData.csv" using 1:5 with lines lw 2 title 'Load (A)' axes x1y2
Sample Data:
time,V_Batt,V_SolarV,A_Charge,A_Load,bool_charging
2014-09-25T07:06:03.358Z,13.20,14.38,0.52,0.03,1
2014-09-25T07:05:03.639Z,13.16,14.14,0.52,0.05,1
2014-09-25T07:04:02.856Z,13.18,14.19,0.54,0.03,1
2014-09-25T07:03:03.141Z,13.18,14.24,0.52,0.03,1
2014-09-25T07:02:03.410Z,13.18,14.09,0.52,0.03,1
2014-09-25T07:01:03.604Z,13.20,14.38,0.54,0.03,1
2014-09-25T07:00:02.766Z,13.11,14.28,0.50,0.02,1
2014-09-25T06:59:03.025Z,13.09,14.28,0.48,0.02,1
2014-09-25T06:58:03.302Z,13.11,14.28,0.43,0.02,1
2014-09-25T06:57:03.445Z,13.18,14.28,0.56,0.05,1
2014-09-25T06:56:02.611Z,13.16,14.14,0.52,0.03,1
2014-09-25T06:55:02.901Z,13.09,14.58,0.48,0.01,1
2014-09-25T06:54:03.178Z,13.09,14.48,0.52,0.02,1
2014-09-25T06:53:03.432Z,13.13,14.53,0.54,0.06,1
2014-09-25T06:52:03.630Z,13.11,14.28,0.48,0.03,1
2014-09-25T06:51:02.763Z,13.16,14.14,0.54,0.05,1
2014-09-25T06:50:03.068Z,13.16,14.28,0.54,0.03,1
2014-09-25T06:49:03.388Z,13.07,14.38,0.50,0.03,1
2014-09-25T06:48:02.683Z,13.09,14.33,0.50,0.03,1
2014-09-25T06:47:02.967Z,13.07,14.04,0.48,0.02,1
2014-09-25T06:46:03.249Z,13.05,14.19,0.48,0.02,1
2014-09-25T06:45:03.410Z,13.09,14.24,0.56,0.06,1
2014-09-25T06:44:02.677Z,13.07,14.24,0.52,0.03,1
2014-09-25T06:43:02.973Z,13.05,14.09,0.50,0.03,1
2014-09-25T06:42:03.282Z,13.09,14.24,0.52,0.03,1
2014-09-25T06:41:03.389Z,12.96,14.04,0.46,0.02,1
2014-09-25T06:40:02.702Z,12.76,13.59,0.50,0.00,1
I would like to add column 6 which is a boolean (0/1) value. In this sample data, the background would be fully highlighted as the bool is always true
Any tips?
You can use the boxes plotting style to draw background boxes depending on the value of column 6, i.e. something like
plot "sampleData.csv" using 1:($6 * 16) with boxes fc rgb '#ccffcc' fillstyle solid,\
"" using 1:2 lt 1 with lines lw 2 title 'Batt (V)'
That, however, requires you to know the maximum and minimum values of the y-range. If that should be calculated automatically, you'll need first to make a dummy plot with the unknown terminal and then use GPVAL_Y_MIN and GPVAL_Y_MAX:
reset
set datafile separator ","
set terminal pngcairo size 800,400
set title "Solar charge monitor"
set yrange [0:]
set ylabel "V"
set y2range [0:]
set y2label "A"
set y2tics
set xlabel "Date"
set xdata time
set timefmt "%Y-%m-%dT%H:%M:%SZ"
set key left center
set grid
set autoscale xfix
set style data lines
set terminal push
set terminal unknown
plot "sampleData.csv" using 1:2, "" using 1:3
set terminal pop
set output "samplePlot.png"
plot "sampleData.csv" using 1:(GPVAL_Y_MIN + $6 * (GPVAL_Y_MAX - GPVAL_Y_MIN)) with boxes fc rgb '#ccffcc' fillstyle solid notitle,\
"" using 1:2 lt 1 lw 2 title 'Batt (V)', \
"" using 1:3 lt 2 lw 2 title 'Solar (V)', \
"" using 1:4 lt 3 lw 2 title 'Charge (A)' axes x1y2, \
"" using 1:5 lt 4 lw 2 title 'Load (A)' axes x1y2
Using a slightly changed data file (I inserted some zeros to show the effect), I get:
If you don't want vertical lines at the boundaries, you could also use filledcurves with:
...
plot "sampleData.csv" using 1:(GPVAL_Y_MIN + $6 * (GPVAL_Y_MAX - GPVAL_Y_MIN)) with filledcurves x1 fc rgb '#ccffcc' fillstyle solid notitle,
...

Gnuplot: how to fill a bar with both a color background and a pattern

I want to fill a bar with both a color background and a pattern. Is it possible in Gnuplot?
I am using Gnuplot 4.6.5
The code I have now:
# set terminal pngcairo transparent enhanced font "arial,10" fontscale 1.0 size 500, 350
# set output 'histograms.2.png'
set boxwidth 0.9 absolute
set style fill solid 1.00 border lt -1
set key inside right top vertical Right noreverse noenhanced autotitles nobox
set style histogram clustered gap 1 title offset character 0, 0, 0
set datafile missing '-'
set style data histograms
set xtics border in scale 0,0 nomirror rotate by -45 offset character 0, 0, 0 autojustify
set xtics norangelimit font ",8"
set xtics ()
set title "US immigration from Northern Europe\nPlot selected data columns as histogram of clustered boxes"
i = 22
set yrange [0:2000]
set style line 1 lc rgb 'orange';
set style line 2 lc rgb 'pink';
plot for [i=2:7] 'data.dat' using i:xtic(1) ti col ls i%2+1;
The data file:
Region Denmark France Demark-Women France-women Demark-man France-men
1891-1900 1000 1100 500 600 500 500
1901-1910 1500 1600 1000 600 500 1000
Here are the links to download the script: https://dl.dropboxusercontent.com/u/45318932/histograms2.plt and data file: https://dl.dropboxusercontent.com/u/45318932/data.dat
The script gives me:
What I want is:
It would be much appreciated if someone can help me improve the code to produce the second figure. Thanks.
That one is very tricky because you cannot change the background color of the fill patterns. And by default the background color of the patterns is white, and not transparent or empty.
The only terminal which can be manipulated adequately is the lua tikz terminal. Here, I first draw all the color boxes, and later in a second iteration the fill patterns. To have a new iteration, I use the newhistogram option, which however causes a gap in the legend.
To remove the white background of the fill patterns, I remove the relevant parts from the output stream with sed. Quite hacky, but it works:
set terminal lua tikz standalone size 5in, 3in color
set output '| sed ''s/\\gpfill{color=gpbgfillcolor}//g'' > histograms.tex'
set boxwidth 0.9 absolute
set style fill solid 1.00 border lt -1
set key inside right top vertical Right noreverse noenhanced autotitles nobox
set style histogram clustered gap 1 title offset character 0, 0, 0
set datafile missing '-'
set style data histograms
set xtics border in scale 0,0 nomirror rotate by -45 offset character 0, 0, 0 autojustify
set xtics norangelimit font ",8"
set xtics ()
set title "US immigration from Northern Europe\nPlot selected data columns as histogram of clustered boxes"
i = 22
set yrange [0:2000]
set xrange [-1:2]
set style line 1 lc rgb 'orange';
set style line 2 lc rgb 'pink';
plot for [i=2:7] 'data.dat' using i:xtic(1) ti columnhead(i > 3 ? 10 : i) ls i%2+1 fillstyle solid noborder,\
newhistogram at -1, \
'' using 2 ti 'total' lt -1 fillstyle empty,\
'' using 3 notitle lt -1 fillstyle empty,\
'' using 4 title 'women' lt -1 fillstyle pattern 5,\
'' using 5 notitle lt -1 fillstyle pattern 5,\
'' using 6 title 'men' lt -1 fillstyle pattern 6,\
'' using 7 notitle lt -1 fillstyle pattern 6
set output
system('pdflatex histograms.tex')
Result with 4.6.5:
Just found out, that you can specify the patterns to have no background color like
... fillstyle pattern 6 transparent
For which terminals that works depends on the gnuplot version:
plot x with filledcurves x1 fillstyle solid fc rgb '#990000',\
x with filledcurves x1 fillstyle pattern 4 transparent lc rgb 'white'
Result (with svg terminal and version 4.6.5):

Stacked and grouped bar histogram with Gnuplot

I would like to reproduce a bar chart like this one, i.e.: multiple groups, every group has many bars (4 bars in my case), each bar is segmented in a few slices (two slices in my case).
In my case, I have four algorithms applied on vectors of different sizes (2^0 to 2^20). Each algorithm has two "sections", local computation and communication. For each vector size I want to show the time required by each algorithm to perform the local computation and the communication, along with the total time corresponding to the sum of these two sections.
As a result, I would like to have a group for every vector size. In each group there are four bars corresponding to the four algorithms and each bar is segmented in a (e.g.) red part corresponding to the local computation and a blue part corresponding to the communication.
Is this feasible with gnuplot? I can provide data in whatever format is useful.
Many thanks in advance.
For your data set it doesn't make sense to stack the local and comm parts, because the comm part is to small to see it in the graph. In any case it would also be quite tricky to combine stacked and clustered, depending on the further requirements (legend entries, tick labels etc).
Here is an example of how to plot a clustered histogram for your data set:
set style histogram clustered gap 1
set style data histogram
set style fill solid 1.0 noborder
set termoption enhanced
set xtics out nomirror
myxtic(x) = sprintf('2^{%d}', int(floor(log(x)/log(2) + 0.5)))
plot 'test.dat' using ($2+$3):xtic(myxtic(stringcolumn(1))) title 'Algorithm 1',\
for [i=2:4] '' using (column(2*i)+column(2*i+1)) title sprintf('Algorithm %d', i)
The result is:
To group by algorithm, you can create new groups with the newhistogram keyword:
set style histogram rowstacked title offset 4,1
set boxwidth 0.9 relative
set style fill solid 1.0 border lt -1
set xtics rotate by 90 right
plot newhistogram "Algorithm 1" lt 1,\
'test.dat' using 2:xtic(1) title columnheader, \
'' using 3 title columnheader,\
newhistogram "Algorithm 2" lt 1,\
'test.dat' using 4:xtic(1) notitle, \
'' using 5 notitle,\
newhistogram "Algorithm 3" lt 1,\
'test.dat' using 6:xtic(1) notitle, \
'' using 7 notitle,\
newhistogram "Algorithm 4" lt 1,\
'test.dat' using 8:xtic(1) notitle, \
'' using 9 notitle
The local and comm dat are stacked, but the comm part is so small, that you cannot see it in the graph (only when you zoom in).
For the output I used 4.6.3 and the following settings:
set terminal pngcairo size 1000,400
set output 'test.png'
set xtics font ',6'
The result is:
A bit more sophisticated display of the xtics requires some tricking, because for histograms the xtics aren't treated as being numerical, but rather strings. Here is an example:
set terminal pngcairo size 1000,400
set output 'test.png'
set style histogram rowstacked title offset 0,-0.5
set bmargin 3
set boxwidth 0.9 relative
set style fill solid 1.0 border lt -1
set termoption enhanced
set xtics out nomirror
myxtic(x) = (int(floor(log(x)/log(2) + 0.5)) % 5 == 0) ? sprintf('2^{%d}', int(floor(log(x)/log(2) + 0.5))) : ""
plot newhistogram "Algorithm 1" lt 1,\
'test.dat' using 2:xtic(myxtic(real(stringcolumn(1)))) title columnheader, \
'' using 3 title columnheader,\
newhistogram "Algorithm 2" lt 1,\
'test.dat' using 4:xtic(myxtic(real(stringcolumn(1)))) notitle, \
'' using 5 notitle,\
newhistogram "Algorithm 3" lt 1,\
'test.dat' using 6:xtic(myxtic(real(stringcolumn(1)))) notitle, \
'' using 7 notitle,\
newhistogram "Algorithm 4" lt 1,\
'test.dat' using 8:xtic(myxtic(real(stringcolumn(1)))) notitle, \
'' using 9 notitle
With the result

Resources