André Rosa
André Rosa

Reputation: 312

How to display y-labels on top of histogram bars on gnuplot

I desgined a histogram in gnuplot however the y-scale needs to be in log2 due to huge difference in values. Therefore, to improve readability of the plot I pretend to display the concrete values on top of each bar. The values represent bytes and so I would like for this values also be in log2 and to be formated to display kb, Mb, ... as is being done in the y-axis. How can I achieve this?

This is the comands I'm currently using:

set terminal postscript eps enhanced dash color "" 13

reset
set datafile separator ","
set title "Bytes per Protocol"
set xlabel "Protocol"
set ylabel "Bytes" rotate by 90
set yrange [0:1342177280]
set logscale y 2
set format y '%.0s%cB'
set style data histogram
set boxwidth 0.5
set style fill solid
set xtics format ""
set grid ytics
set style data histogram
set style histogram clustered gap 2
set grid ytics
set tic scale 0
set size 1,0.9
set size ratio 0.5
set key autotitle columnhead
set output "ex_a_1_BIG.eps"
plot "ex_a_1_BIG.csv" using ($3):xtic(1) title "IN", \
               '' using ($5):xtic(1) title "OUT", \
               '' using 0:($3):($3) with labels center offset -2,1 notitle, \
               '' using 0:($5):($5) with labels center offset 2,1 notitle

This is the content of the csv I want to plot (I only want the bytes in and out):

protocol,packets in,bytes in,packets out,bytes out
ICMP,1833,141562,979,60334
IGMP,0,0,283,14006
TCP,158214,129221151,130101,47734355
UDP,68476,9571677,72530,24310734

enter image description here

Upvotes: 0

Views: 689

Answers (1)

theozh
theozh

Reputation: 25684

Check help format_specifiers and help gprintf. And the example below.

What is a bit unfortunate, that in gnuplot apparently the prefix for 1 to 999 is a single space instead of an empty string. For example, with the format '%.1s %cB' this leads to two spaces for 1-999 B and one space for the others, e.g. 1 kB. However, if you use '%.1s%cB' this leads to one space for 1-999 B and no space for the others e.g. 100kB. As far as I know, correct would be one space between the number and the units. I'm not sure whether there is an easy fix for this.

Code:

### prefixes 
reset session

$Data <<EOD
1  1
2  12
3  123
4  1234
5  12345
6  123456
7  1234567
8  12345678
9  123456789
10 1234567890
11 12345678901
12 123456789012
13 1234567890123
EOD

set boxwidth 0.7
set style fill solid 1.0
set xtics 1
set yrange [0.5:8e13]

set multiplot layout 2,1
    set logscale y     # base of 10
    set format y '%.0s %cB'
    plot $Data u 1:2 w boxes lc rgb "green" notitle, \
         '' u 1:2:(gprintf('%.1s %cB',$2)) w labels offset 0,1 not

    set logscale y 2   # base of 2
    set format y '%.0b %BB'
    plot $Data u 1:2 w boxes lc rgb "red" notitle, \
         '' u 1:2:(gprintf('%.1b %BB',$2)) w labels offset 0,1 not
unset multiplot
### end of code

Result:

enter image description here

Addition:

a workaround for number/unit space issue at least for the labels in the graph would be:

myFmt(c) = column(c)>=1 && column(c)<1000 ? \
           gprintf('%.1s%cB',column(c)) : gprintf('%.1s %cB',column(c))

and

plot $Data u 1:2 w boxes lc rgb "green" notitle, \
         '' u 1:2:(myFmt(2)) w labels offset 0,1 not

But for the ytics labels I still don't have an idea.

Upvotes: 3

Related Questions