As usual, we give the gnu script first, and then dissect it, step by step.

reset f(x, a, b, c) = a*exp(-(x-b)*(x-b)/c/c) A = 0.6 B = 0.5 C = 0.2 unset key unset colorbox unset xtics set ytics 0,1,4 set parametric set urange [0:0.5] set vrange [0:1] set pm3d map set xrange [0:10] set yrange [0:4] set multiplot set isosamples 100, 100 set palette model HSV function 2.0/3.0, 0.4-0.4*gray, (4.0+2.0*gray)/6.0 splot 20*u, 4*v, 2*u+v w pm3d set isosamples 100, 2 set palette model HSV function 0.95, 1-f(gray, A, B, C), (1+2*f(gray, A, B, C))/3 splot u+1,v,u w pm3d,\ u+2,2*v,u w pm3d, \ u+3,3*v,u w pm3d, \ u+4,2*v,u w pm3d, \ u+5,3*v,u w pm3d, \ u+6,3.5*v,u w pm3d, \ u+7,1.4*v,u w pm3d, \ u+8,3*v,u w pm3d, \ u+9,1*v,u w pm3d unset multiplot

First, we define the function according to which we are going to colour the bars. This is done by defining f(x,a,b,c) and the parameters A, B, and C. The the following couple of lines define the graph properties. The first relevant line is in blue, where we draw the background of our graph. We define the palette for pm3d using the HSV colour space. As in RGB, the colour is given as a triplet, the first member of which is the hue (in this case it will be something close to blue), the second is the saturation, which we defined to be whiter, if the value of gray is higher, and finally, the value. We then plot '20*u, 4*v, 2*u+v' on our map. By plotting the value 2*u+v, we will get a gradient that runs from bottom to top, left to right. You can modify this, if you want to change the direction in which the background becomes whiter.

Having drawn the background, we can plot the bars. This is done in the next step, where we always plot something like 'u+shift,value*v,u', where shift is the position of the bar, and value is its height. Note that before calling splot, we re-defined our palette, using the function f(x,a,b,c) from the beginning of the script. 'a' will set how white the colour becomes, 'b' is the position of the highest saturation value (or the centre of the pattern), and 'c' determines how tight the colour gradient is.

Now, let us see how this procedure can be automated. As previously, we will use a gawk script, which processes a data file with N+1 columns, the first setting the label, and the last N containing N values (i.e., instead of on set of bars, we will have N sets bars). Here is the script,

#!/bin/bash gawk 'BEGIN {i=0; max=0} { if($0!~/#/) { label[i] = $1 for(j=2;j<=NF;j++) { v[i,j-1] = $j if(max<v[i,j-1]) max=v[i,j-1] } i++ } } END { print "reset" print "f(x, a, b, c) = a*exp(-(x-b)*(x-b)/c/c)" print "A = 0.6; B = 0.5; C = 0.2" print "unset key; unset colorbox; unset xtics; set pm3d map" printf "set yrange [0:%f]\n", max printf "set parametric; set urange [0:%f]; set vrange [0:1]\n", 1.0/(j-1) printf "set xrange [0:%d]\n", i+1 print "set multiplot" print "set isosamples 100, 100" print "set palette model HSV functions 2.0/3.0, 0.4-0.4*gray, (4.0+2.0*gray)/6.0" printf "splot %d*u, %f*v, 2*u+v w pm3d\n", (i+1)*(j-1), max print "set isosamples 100, 2" for(l=1;l<j-1; l++) { if(l==j-2) { for(k=0;k<i;k++) { printf "set label %d \"%s\" at %f, -%f rotate by 45\n", k+1, label[k], k+0.5, max/5.0 } } if(l>1) print "unset ytics; unset ylabel" printf "set palette model HSV function %f, 1.0-f(gray, A, B, C), (1.0+2.0*f(gray, A, B, C))/3.0\n", 1.0/l printf "splot " for(k=0;k<i;k++) { printf "u+%f,%f*v,u w pm3d,\\\n", k+l/(j-1), v[k,l] } printf "u+%f,%f*v,u w pm3d\n", i+l/j, v[i,l] } print "unset multiplot" }' $1

and here is the data file that I used to produce the figure below:

First 1.0 2.0 1.0 Second 1.0 1.1 3.2 Third 2.0 1.2 3.4 Fourth 1.2 2.4 1.1 Fifth 1.6 2.1 1.5

I believe, it should be fairly easy to hack the script to suit your needs. The points of interest are the colour of the background and the bars, and the position of the labels. Small tweaks in the script will give you just anything you would want. Next time I will come back to this script, and we will see how this can be modified to produce stacked bargraphs. So long!

Hi,

ReplyDeleteI came across your blog looking for a way to generate stacked bar charts with x-entries given as dates. I see you're planning to discuss how to stack the bars, so I'll wait patiently... Is this mechanism compatible with date values? Thanks for the blog, I got a number of ideas looking over your examples!

Hi,

ReplyDeleteI was searching some commands in gnuplot and came to your blog.

Can you tell me, how to draw inequalities in two dimension by gnuplot by directly giving the set of inequalities and the x-y range, so that it shades the required region.

Regards, thanks and keep posting.

Hi Omri,

ReplyDeleteI worked out the stacked graphs, and published them today. I am not sure whether this is what you would like to have.

As for the date data, I think, you've got to sort that in advance. I believe, you could do this (if you are using linux) using the -M switch of sort, or you could also look at this page

sorting by date

Alternatively, you could check out the functions handling time in (g)awk. There is a chapter in Arnold Robbins' gawk manual titled 'Turning dates into timestamps', which should be applicable here. If you perhaps could give an example of your file, I would be glad to try my hand at it.

I hope this helps.

Cheers,

I have posted the solution to the question on how to plot inequalities. Let me know, if this is not what you had in mind.

ReplyDeleteCheers,

gnuplotter

Regarding dates & sorting, I use perl, where it's easy enough to find modules which will handle all of this. My difficulty lies in combining the parametric splot commands you're using with gnuplot's timefmt, "set xdata time" mode, etc. But then again, I'm new to gnuplot so I might be missing something. Thanks again!

ReplyDelete- Omri