Faysal
Faysal

Reputation: 35

How to draw rowstacked histogram in gnuplot with value labels in each bar

I want to draw a rowstacked histogram. The following is what I have so far:

enter image description here

I have used the code below:

reset
set bmargin 10
set lmargin 20
set rmargin 16
set tmargin 7
show margin  

set title "" font "Verdana,27"
show title
set grid

set xlabel offset 0,-5 font "Verdana,25"
set xlabel "Number of Cores"
show xlabel
set xtics font "Verdana,18"

set ylabel offset -4,0 font "Verdana,25"
set ylabel "Time (%)"
show ylabel
set yrange [0:130]
set ytics font "Verdana,18"  
set ytics (0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100)

set style data histogram
set style histogram rowstacked title offset 0,3
set style fill solid border lt -1
set boxwidth 0.9

set key right
set key font "Verdana,17"
set key autotitle columnheader horizontal


plot newhistogram '{/=22 1-Core}', \
        for [i=2:5] 'base_vs_FHA_speedup_1core.dat' using i:xtic(1), \
     newhistogram '{/=22 2-Cores}' lt 1, \
        for [i=2:5] 'base_vs_FHA_speedup_2core.dat' using i:xtic(1) notitle, \
     newhistogram '{/=22 4-Cores}' lt 1, \
        for [i=2:5] 'base_vs_FHA_speedup_4core.dat' using i:xtic(1) notitle, \
     newhistogram '{/=22 8-Cores}' lt 1, \
        for [i=2:5] 'base_vs_FHA_speedup_8core.dat' using i:xtic(1) notitle

I have 4 different data files with sample data like this

Configuration col1 col2 col3 col4 col5

base_vs_FHA_1core.dat

Base        5       50      40.5    4.5             
FHA         5       16      38      5       1.54x

base_vs_FHA_2core.dat

Base        9.3     47      37.3    6.3             
FHA         9.3     15      34.3    6.3     1.54x

base_vs_FHA_4core.dat

Base        18      41      33.9    7.06                
FHA         16.6    13.07   30.7    7.4     1.47x

base_vs_FHA_8core.dat

Base        27.7    34.3    28.3    9.6             
FHA         28.3    11.45   25.3    9.6     1.34x

I want to have each bar in the histogram labeled with the corresponding value and the value of the last column on the top of the second histogram in each pair. How can I achieve this?

Can I merge all the 4 files and achieve the same goal?

Upvotes: 1

Views: 427

Answers (1)

theozh
theozh

Reputation: 25684

You can merge all 4 files in one file. I would recommend a separation with two empty lines, because with this, you can easily address the (sub)datablocks via index, check help index.

For the labels you can make a double loop, one for the (sub)datablocks and one for the columns. You have to sum up the columns (check help sum) to calculate the y-position of the label (i.e. center of the histogram element). The x-position of the labels is special for the first dataset (since only this has a columnheader), this is taken into account with (i*3+$0-(i==0)), i.e. i==0 will return 1 if i equals 0, and 0 otherwise.

Instead of setting a large fontsize many times you might want to set it in the terminal, e.g. something like: set term pngcairo font ",17".

Find below a minimized example as a starting point for further optimization.

Script:

### rowstacked histogram with numbers in corresponding boxes
reset session

$Data <<EOD
# base_vs_FHA_1core.dat
col1 col2 col3 col4 col5
Base 5 50 40.5 4.5
FHA  5 16 38 5 1.54x


# base_vs_FHA_2core.dat
Base 9.3 47 37.3 6.3
FHA  9.3 15 34.3 6.3 1.54x


# base_vs_FHA_4core.dat
Base 18   41    33.9 7.06
FHA  16.6 13.07 30.7 7.4  1.47x


# base_vs_FHA_8core.dat
Base 27.7 34.3  28.3 9.6
FHA  28.3 11.45 25.3 9.6 1.34x
EOD

set xlabel "Number of Cores"
set ylabel "Time (%)"
set yrange [0:130]
set ytics 0, 10, 100
set grid

set style data histogram
set style histogram rowstacked title
set style fill solid 0.5 border lt -1
set boxwidth 0.9
set key top left noautotitle horizontal

N = 5   # number of last data column

plot newhistogram '1-Core' at 0, \
        for [i=2:N] $Data index 0 u i:xtic(1) ti columnheader, \
     newhistogram '2-Cores' lt 1 at 3, \
        for [i=2:N] '' index 1 u i:xtic(1), \
     newhistogram '4-Cores' lt 1 at 6, \
        for [i=2:N] '' index 2 u i:xtic(1), \
     newhistogram '8-Cores' lt 1 at 9, \
        for [i=2:N] '' index 3 u i:xtic(1), \
    for [i=0:3] for [j=2:N] '' index i u (i*3+$0-(i==0)): \
        ((sum [k=2:j] column(k))-column(j)*0.5):j w labels
### end of script

Result:

enter image description here

Upvotes: 2

Related Questions