devil
devil

Reputation: 1839

Gnuplot - How to place y-values above bars when using Histogram style?

I am currently using a script to generate histogram plots, e.g., by doing:

set style histogram cluster gap 4
plot for [COL=2:10] 'example.dat' u COL:xticlabels(1) title columnheader(COL)

Now I wish to add the y-values (numbers) above the bars in the histogram but adding w labels gives the 'Not enough columns for this style' error.

plot for [COL=2:10] 'example.dat' u COL:xticlabels(1) title columnheader(COL), \
    for [COL=2:10] 'example.dat' u COL title '' w labels

Is it possible to add y-labels using the histogram style?

Note: I know that there are examples for plotting with boxes. I wish to make this work with the histogram style if possible.

Upvotes: 2

Views: 4205

Answers (1)

mgilson
mgilson

Reputation: 310287

Here's a test datafile I came up with:

example.dat

 hi world foo bar baz qux
 1   2     3   4   5   6    
 4   5     7   3   6   5    

Here's the script I used to plot it:

set yrange [0:*]
GAPSIZE=4
set style histogram cluster gap 4
STARTCOL=2                 #Start plotting data in this column (2 for your example)
ENDCOL=6                   #Last column of data to plot (10 for your example)
NCOL=ENDCOL-STARTCOL+1     #Number of columns we're plotting 
BOXWIDTH=1./(GAPSIZE+NCOL) #Width of each box.
plot for [COL=STARTCOL:ENDCOL] 'example.dat' u COL:xtic(1) w histogram title columnheader(COL), \
    for [COL=STARTCOL:ENDCOL] 'example.dat' u (column(0)-1+BOXWIDTH*(COL-STARTCOL+GAPSIZE/2+1)-0.5):COL:COL notitle w labels

Each cluster of histograms takes a total width of 1 unit on the x axis. We know how many widths we need (the number of boxes +4 since that is the gapsize). We can calculate the width of each box (1/(N+4)). We then plot the histograms as normal. (Note that I added with histogram to the plot command).

According to the builtin help, labels require 3 columns of data (x y label). In this case, the y position and the label are the same and can be read directly from the column COL. The x position of the first block is centered 0 (and has a total width of 1). So, the first block is going to be located at x=-0.5+2*BOXWIDTH. The 2 here is because the gap is 4 boxwidths -- two on the left and 2 on the right. The next block is going to be located at -0.5+3*BOXWIDTH, etc. In general, (as a function of COL) we can write this as

-0.5+BOXSIZE*(COL-STARTCOL+1+GAPSIZE/2)

We need to shift this to the right by 1 unit for each additional block we read. Since each block corresponds to 1 line in the data file, we can use pseudo-column 0 (i.e. column(0) or $0) for this since it gets incremented for each "record/line" gnuplot reads. The 0th record holds the titles, the first record holds the first block. Since we want a function which returns 0 for the first record, we use column(0)-1. Putting it all together, we find that the x-position is:

(column(0)-1-0.5+BOXSIZE*(COL-STARTCOL+1+GAPSIZE/2))

which is equivalent to what I have above.

Upvotes: 9

Related Questions