Friday, 2 October 2009

The turning of the histogram

I have been off for some time now, and I thought that it would be high time to post something on gnuplot. I have chosen an easy subject, but one that could turn out to be useful. At least, I have seen people searching for a solution to this problem with the histograms. If you needed it in the past, you have probably realised that gnuplot can make only vertical histograms. But sometimes, this is not the best way to represent data, and a horizontal version would be much better. For one thing, the horizontal one might take up much less space. If you want to learn how to produce the figure below, keep reading!

Making the graphs will require some work, but everything is quite straightforward. What we should note, however, is that we will still produce an upright image that we have to rotate later. If you set the terminal to postscript, you will probably use the figure in LaTeX, where you simply have to tell the compiler to rotate the figure by 90 degrees. If you set the terminal to a raster format, or print the screen, you can rotate the image in many applications, but if you want to adhere to the command line, you can, at least, under Linux, use the convert command as
convert -rotate 90 figure_in.png figure_out.png

The figure above was produced based on the following data file
1989 0.1
1990 0.2
1991 0.2
1992 0.05
1993 0.15
1994 0.3
1995 0.1

(We have seen these data many times, you should know it by heart by now!) After this interlude, let us see the code! I will discuss it afterwards.
set key at graph 0.24, 0.85 horizontal samplen 0.1
set style data histogram
set style histogram cluster gap 1
set style fill solid border -1
set boxwidth 0.8
set xtic rotate by 90 scale 0
unset ytics
set y2tics rotate by 90
set yrange [0:0.35]; set xrange [-0.5:6.5]
set y2label 'Output' offset -2.5
set xlabel ' '
set size 0.6, 1
set label 1 'Year' at graph 0.5, -0.1 centre rotate by 180
set label 2 'Nowhere' at graph 0.09, 0.85 left rotate by 90
set label 3 'Everywhere' at graph 0.2, 0.85 left rotate by 90
p 'pie.dat' u 2 title ' ', '' u ($2/2.0+rand(0)/10.0) title ' ', '' u 0:(0):xticlabel(1) w l title ''

The first line after the reset is required, because we have to make our key ourselves. We simply specify the coordinates and that that we want to have a horizontal key (i.e., one in which the keys are placed to the right of the previous one), with a length of 0.1. If you want smaller or larger space between the keys, you can modify this, by adding the spacing flag to the set command. You can see the exact syntax by issuing ?key in the gnuplot prompt.
In the next four lines, we set up our histogram. The content of these lines might depend on what exactly we intend to plot. For more on this, check out the gnuplot demo page! We then rotate the xtics by 90 degrees. We do this, because the whole image will be rotated, and by rotating the xtics, we make sure that those will be horizontal at the end. For the very same reason, we also unset the ytics, and set the y2tics. We also set the y2label and xlabel. This latter one is empty, but we still need the space for it, so we set it to ' '. Beware the white space!

The next important step is the setting of the aspect ratio of our figure, which will be 0.6:1. Having done that, we introduce 3 labels: one for the xlabel, and two for the key. The placement of these labels is somewhat arbitrary, and depends on the particular terminal that you use. But only these three numbers and the coordinates of the key need any tweaking, really. At the very end, we plot our data. I plotted the second column twice, with an added random numbers, so that we can have two columns at each data point. Note that we plot the first column, too, but pass it to the xlabel command. By doing that, we can automate the labelling of the xtics, using the first column in our data file. Also note the specification of the titles: in the first two cases, the single quotes include a white space, while in the third one, there is nothing.


  1. Thanks for the tutorial! I coulnd't make it do what I wanted easily, which is to have a cascade of horizontal histograms, one for each xtic, so I had to find a different solution. I thought I'd add it here :)

    I simply use the "object" command in gnuplot to create the rectangles to form my histograms! My program which creates the dataset then simply prints out a bunch of rectangle declarations, which I then paste into my gnuplot .p file. In the example, I have an x-axis going from 0 to 44, in steps of 4. Each histogram occupies the space in such an interval.

    set xrange [0 : 45];
    set xtics 0, 4;

    # histogram in [0, 4]
    set object 1 rect from 0,287 to 0.01,289 fc rgb "white" fs empty border -1 lw 0.4;

    # histogram in [4, 8]
    set object 2 rect from 4,287 to 4.09,289 fc rgb "white" fs empty border -1 lw 0.4;
    set object 3 rect from 4,291 to 6.71,293 fc rgb "white" fs empty border -1 lw 0.4;

    # histogram in [8, 12]
    set object 4 rect from 8,287 to 8.01,289 fc rgb "white" fs empty border -1 lw 0.4;
    set object 5 rect from 8,291 to 8.24,293 fc rgb "white" fs empty border -1 lw 0.4;
    set object 6 rect from 8,295 to 11.64,297 fc rgb "white" fs empty border -1 lw 0.4;

    ... etc ...

    Then, after this, I do the "plot" command, which is then overlaid on the histograms -- as desired.

    - joakimk

  2. Hi,
    Can you please share a sample implementation. I couldnt make it work.

  3. Good Article about The turning of the histogram

    Post by
    Term Papers