gnuplot partially stacked bars - gnuplot

I would like to make a gnuplot graph with one full bar and another one stacked.
The data is something like
x data E M L
[10,20) 0.000000 1.081916 2.0958133 5.473606
[20,40) 0.000000 2.331769 2.1402838 4.528341
[40,80) 3.262375 2.201788 1.3499280 3.023847
>80 2.368121 2.132216 0.7322889 2.610368
where E, M and L are the three "green" components.
I have tried to do something like
set style data histograms
set style histogram rowstacked
#set style histogram cluster gap 1
set style fill solid
...
plot newhistogram, "size_class_data/tree_paracou.txt" using 2:xticlabel(1) linecolor rgb data_color title "Model",\
newhistogram, '' using 3:xticlabel(1) linecolor rgb early_color title "d",\
'' using 4 linecolor rgb mid_color title "g",\
'' using 5 linecolor rgb late_color title "f"
but the two graphs lie on two different parts of the x axis.

The newhistogram command has an option at for setting the coordinate of the first box.
In you case you can fix the boxwidth, and start the second histogram at 0 + boxwidth:
set style data histograms
set style histogram rowstacked
set style fill solid
set boxwidth 0.33 absolute
plot "foo.dat" using 2:xticlabel(1) skip 1 linecolor rgb "black" title "Model",\
newhistogram at 0.33, '' using 3 skip 1 linecolor rgb "red" title "d",\
'' using 4 skip 1 linecolor rgb "green" title "g",\
'' using 5 skip 1 linecolor rgb "blue" title "f"

Related

gnuplot histogram chart with overlap

I would like to plot a bar chart or histogram like this in gnuplot.
I tried set style histogram rowstacked which is a start but it adds the columns on top of each other while I need them overlapped. Next is the issue of transparent color shading.
Thanks for your feedback.
UPDATE: user8153 asked for additional data.
The set style histogram clustered gap 0.0 is doing the cluster mode of the histogram bars. If you blur the eye it sort-of shows what I want but with overlap and transparent shading.
The only other histogram modes given in the docs are rowstacked and columnstacked. I never got a plot out of columnstacked so I discarded it. Now rowstacked stacks the histogram bars.
The overlay appearance is there but it is wrong. I don't want the stacked appearance. The histograms have to overlay.
Code :
set boxwidth 1.0 absolute
set style fill solid 0.5 noborder
set style data histogram
set style histogram clustered gap 0.0
#set style histogram rowstacked gap 0.0
set xtics in rotate by 90 offset first +0.5,0 right
set yrange [0:8000]
set xrange [90:180]
plot 'dat1.raw' using 3 lc rgb 'orange', \
'dat2.raw' using 3 lc rgb 'blue', \
'dat3.raw' using 3 lc rgb 'magenta'
Thanks for your feedback.
Given a sample datafile test.dat
-10 4.5399929762484854e-05
-9 0.0003035391380788668
-8 0.001661557273173934
-7 0.007446583070924338
-6 0.02732372244729256
-5 0.0820849986238988
-4 0.20189651799465538
-3 0.4065696597405991
-2 0.6703200460356393
-1 0.9048374180359595
0 1.0
1 0.9048374180359595
2 0.6703200460356393
3 0.4065696597405991
4 0.20189651799465538
5 0.0820849986238988
6 0.02732372244729256
7 0.007446583070924338
8 0.001661557273173934
9 0.0003035391380788668
10 4.5399929762484854e-05
you can use the following commands
set style fill transparent solid 0.7
plot "test.dat" with boxes, \
"test.dat" u ($1+4):2 with boxes
to get the following result (using the pngcairo terminal):
Using transparency as in user8153's solution is certainly the easiest way to visualize an overlap of two histograms.
This works even if the two histogram do not have identical bins or x-data-ranges.
However, the color of the overlap is pretty much bound to the colors of the two histogram and the level of transparency. Furthermore, if you want to show the overlap in the key you have to do it "manually".
Here is a solution where you can choose an independent color for the overlap area.
The overlap is basically the minimum y-value from both histograms for each x-value.
For this you need to compare the y-values for each x-value. This can be done in gnuplot with some "trick" by merging the two files line by line. This requires the data in a datablock (how to get it there from a file). Since this merging procedure is using indexing of datablock lines, it requires gnuplot>=5.2.0.
This assumes that you have the same x-range and bins for each histogram. If this is not the case, you have to implement some further steps.
Script: (works with gnuplot>=5.2.0, Sept. 2017)
### plot overlap of two histograms
reset session
# create some random test data
set samples 21
f(x,a,b) = 1./(a*(x-b)**4+1)
set table $Data1
plot '+' u 1:(f(x,0.01,-2)) w table
set table $Data2
plot '+' u 1:(f(x,0.02,4)) w table
unset table
set boxwidth 1.0
set grid y
set ytics 0.2
set multiplot layout 2,1
set style fill transparent solid 0.3
plot $Data1 u 1:2 w boxes lc 1 ti "Data1", \
$Data2 u 1:2 w boxes lc 2 ti "Data2"
set print $Overlap
do for [i=1:|$Data1|] { print $Data1[i].$Data2[i] }
set print
set style fill solid 0.3
plot $Data1 u 1:2 w boxes lc 1 ti "Data1", \
$Data2 u 1:2 w boxes lc 2 ti "Data2", \
$Overlap u 1:($2>$4?$4:$2) w boxes lc "red" ti "Overlap"
unset multiplot
### end of script
Result:

Gnuplot columnstacked histogram with errorbars

Suppose I have the following data file, so-qn.dat:
Type on on-err off off-err
good 75 5 55 4
bad 15 2 30 3
#other 10 1 15 2
which contains values on columns 2 and 4 and corresponding error deltas on columns 3 and 5.
I can produce a columnstacked histogram:
#!/usr/bin/gnuplot
set terminal png
set output 'so-qn.png'
set linetype 1 lc rgb "blue" lw 2 pt 0
set linetype 2 lc rgb "dark-red" lw 2 pt 0
set style data histograms
set style histogram columnstacked
set style fill solid
set ylabel "% of all items"
set yrange [0:100]
set boxwidth 0.75
set xtics scale 0
set xlabel "Option"
plot 'so-qn.dat' using 2 ti col, \
'' using 4:key(1) ti col
But I can’t figure out how to add errorbars to this. The closest I got so far is with
plot 'so-qn.dat' using 2 ti col, '' using 2:3 with yerrorbars lc rgb 'black' ti col, \
'' using 4:key(1) ti col, '' using 4:5:key(1) with yerrorbars lc rgb 'black' ti col
which produces
but only one of the error bars is in the right spot (I actually have no idea where the bottom left one gets its y from), one is completely invisible (hidden behind the right stack?), and I’d like the error bars to not show up in the key.
Is it possible to combine column-stacked histograms and error bars?
You can add errorbars to column-stacked histograms by manually adding plot-commands for the errorbars. To do so, you need, however, to keep track of the y-positions.
Therefore, let's introduce two variables which store the y-position for each of the two columns' errorbars.
y1 = -2
y2 = -4
You need to initialize these variables with -(number of column)
Next, let us define two functions that update the variables y1, y2.
f1(x) = (y1 = y1+x)
f2(x) = (y2 = y2+x)
Now, generate the desired plot via
plot 'so-qn.dat' using 2 ti col, \
'' using 4:key(1) ti col, \
'' using (0):(f1($2)):3 w yerr t "", \
'' using (1):(f2($4)):5 w yerr t ""
As you can see, you can supress the errorbars in the key by assigning an empty title (t ""). This approach even gives you more flexibility in customizing the appearance of the errorbars (e.g., assign different linestyles etc.).
This being said, I personally think this visualization is rather confusing. You might want to consider another visualization:
set bars fullwidth 0
set style data histograms
set style fill solid 1 border lt -1
set style histogram errorbars gap 2 lw 2
plot 'so-qn.dat' using 2:3:xtic(1) ti columnhead(2), \
'' using 4:5:xtic(1) ti columnhead(4)

GNUplot - plot data file (simple X and Y columns) - setting suitable color and scale on a figure

I have a simple file with two columns:
1 0.005467
2 0.005333
3 0.005467
4 0.005467
5 0.005600
6 0.005600
7 0.005467
8 0.005467
In the first column I have the x-axis values, while on the second column I have y-axis values. I would like to plot a figure of this data. I wrote a gnuplot script for this:
#!/usr/bin/gnuplot
set xlabel "test"
set ylabel "value"
set grid ytics lt 0 lw 1 lc rgb "#bbbbbb"
set grid xtics lt 0 lw 1 lc rgb "#bbbbbb"
set autoscale
set terminal postscript portrait enhanced mono dashed lw 1 'Helvetica' 14
set style line 1 lt 1 lw 3 pt 3 linecolor rgb "red"
set output 'out.eps'
plot 'data.txt' using 2:1 w points title "tests"
And, the output:
But of course, as a newbie in gnuplot, I have some troubles:
How to change the crosses on the fingure into dots?
How to change the color of the dots, to let's say, red? ( my command in my gnuplotscript seems not to work at all ...)
For the first test the adequate, accurate, exact value is 0.005467 but on my figure it doesnt look like so... I would like to place the dot on my figure for the first, second, third, (so on) test on the exact place, where is appropriate value.
How to add a grid to my figure? - SOLVED
How to get rid of the ugly text: 'data.txt' using 1:2 and replace it with a legend? - SOLVED
EDIT (SOLVED ISSUE NO 5)
plot 'data.txt' using 1:2 w points title "tests"
EDIT (SOLVED ISSUE NO 4)
set grid ytics lt 0 lw 1 lc rgb "#bbbbbb"
set grid xtics lt 0 lw 1 lc rgb "#bbbbbb"
You should read a bit in the documentation about all your commands!
Several remarks:
If you want colored points, you shouldn't use the mono (i.e. the monochrome) option, but rather color.
Your definition of the line style is correct, but in order to use it you must use linestyle 1 when plotting. Otherwise the linetype 1 is used. Compare:
set style line 1 lt 1 lw 3 pt 3 linecolor rgb "red"
plot x, 2*x linestyle 1
In order to see all the dots of a terminal, use the test command:
set terminal postscript eps enhanced color dashed lw 1 'Helvetica' 14
set output 'test.eps'
test
set output
You see, that for filled dots you must use pt 7.
I'm sure, that the points are shown at the correct values. Use
set ytics add (0.005467)
to see this.

Gnuplot change color of bars in histogram

is it possible to change the color of bars in a Gnuplot script dynamically?
I have the following script
reset
fontsize = 12
set term postscript enhanced eps fontsize
set output "bargraph_speedup.eps"
set style fill solid 1.00 border 0
set style histogram
set style data histogram
set xtics rotate by -45
set grid ytics linestyle 1
set xlabel "Benchmarks" font "bold"
set ylabel "Relative execution time vs. reference implementation" font "bold"
set datafile separator ","
plot 'bm_speedup.dat' using 2:xtic(1) ti "Speedup" linecolor rgb "#00FF00"
which generates this plot:
Is it possible to make the color of the bars which are below zero red?
Thanks,
Sven
You can mimic this behavior using the boxes style:
My test data:
zip 2
baz 2
bar -1
cat 4
foo -3
And then plotting with gnuplot:
set style line 1 lt 1 lc rgb "green"
set style line 2 lt 1 lc rgb "red"
set style fill solid
plot 'test.dat' u (column(0)):2:(0.5):($2>0?1:2):xtic(1) w boxes lc variable
# #xval:ydata:boxwidth:color_index:xtic_labels
You could split your data file into two parts, positive values and negative, and plot them separately:
plot 'bm_speedup_pos.dat' using 2:xtic(1) ti "Faster" linecolor rgb "#00FF00", \
'bm_speedup_neg.dat' using 2:xtic(1) ti "Slower" linecolor rgb "#FF0000"
Or, if you only need to generate a few graphs, a few times, a common technique is to generate the raw graph in gnuplot, then post-process it in an image editor to adjust the colors. If you go that route, I suggest having gnuplot generate the graph in SVG format, which will give you much better looking graphs than any of the bitmap formats.
Doesn't seem like histogram lets you do it. May be like this:
set boxwidth 0.3
f(v)=v<0?1:2
plot 'bm_speedup.dat' using 0:2:(f($2)):xticlabels(1) with boxes ti "Speedup" lc variable
Actually you can also use linecolor rgb variable and give the color like this:
plot 'bm_speedup.dat' using 2:xtic(1):($2 >= 0 ? 0x00FF00 : 0xFF0000) ti Speedup lc rgb variable

Different coloured bars in gnuplot bar chart?

I have a very simple dataset:
Critical 2
High 18
Medium 5
Low 14
Creating a bar chart in gnuplot out of this dataset is easy, but all the bars are the same colour. I want to have it so that Critical is black, high is red, etc, but there seem to be hardly any online tutorials for doing this.
Can anyone point me in the right direction?
set xrange [-.5:3.5]
set yrange [0:]
set style fill solid
plot "<sed 'G;G' test.dat" i 0 u (column(-2)):2:xtic(1) w boxes ti "Critical" lc rgb "black",\
"<sed 'G;G' test.dat" i 1 u (column(-2)):2:xtic(1) w boxes ti "High" lc rgb "red" ,\
"<sed 'G;G' test.dat" i 2 u (column(-2)):2:xtic(1) w boxes ti "Medium" lc rgb "green",\
"<sed 'G;G' test.dat" i 3 u (column(-2)):2:xtic(1) w boxes ti "Low" lc rgb "blue"
This takes sed and triple spaces your file so that gnuplot sees each line as a different dataset (or "index"). You can plot each index separately using index <number> or i <number> for short as I have done. Also, the index number is available as column(-2) which is how we get the boxes properly spaced.
Possibly a slightly more clean (gnuplot only) solution is using filters:
set xrange [-.5:3.5]
set yrange [0:]
set style fill solid
CRITROW(x,y)=(x eq "Critical") ? y:1/0
HIGHROW(x,y)=(x eq "High") ? y:1/0
MIDROW(x,y) =(x eq "Medium") ? y:1/0
LOWROW(x,y) =(x eq "Low") ? y:1/0
plot 'test.dat' u ($0):(CRITROW(stringcolumn(1),$2)):xtic(1) w boxes lc rgb "black" ti "Critical" ,\
'' u ($0):(HIGHROW(stringcolumn(1),$2)):xtic(1) w boxes lc rgb "red" ti "High" ,\
'' u ($0):(MIDROW(stringcolumn(1),$2)):xtic(1) w boxes lc rgb "green" ti "Medium" ,\
'' u ($0):(LOWROW(stringcolumn(1),$2)):xtic(1) w boxes lc rgb "blue" ti "Low"
This solution also doesn't depend on any particular ordering in your datafile (which is why I prefer it slightly to the other solution. We accomplish the spacing here with column(0) (or $0) which is the record number in the dataset (in this case, the line number).
Here is how you can do this using the linecolor variable option.
If you know, that the lines are always in the same, known order, you can use the row number (zeroth column, $0) as linetype index:
set style fill solid noborder
set linetype 1 lc rgb 'black'
set linetype 2 lc rgb 'red'
set linetype 3 lc rgb 'yellow'
set linetype 4 lc rgb 'green'
set yrange [0:*]
unset key
plot 'alerts.txt' using 0:2:($0+1):xtic(1) with boxes linecolor variable
If the order may vary, you can use a gnuplot-style indexing function, which determines the index of the warning level from a string with space-separated words:
alerts = 'Critical High Medium Low'
index(s) = words(substr(alerts, 0, strstrt(alerts, s)-1)) + 1
set style fill solid noborder
set linetype 1 lc rgb 'black'
set linetype 2 lc rgb 'red'
set linetype 3 lc rgb 'yellow'
set linetype 4 lc rgb 'green'
set yrange [0:*]
unset key
plot 'alerts.txt' using 0:2:(index(strcol(1))):xtic(1) with boxes linecolor variable

Resources