Saturday, January 21, 2012

Plotting a grid on a projected gnuplot graph (e.g. Mollweide)


Following the first post on how to plot a map on gnuplot, and then how to plot it with a Mollweide projection (all in the same post), I decided to dedicate a post on how to do a grid overlay.

Mostly because I first thought the best idea would be to simply plot a file with data points only on the meridians and parallels. This is a bit of a kludge and doesn't allow you to easily add styles to the lines.

The obvious solution: to plot the function that describes the lines of our grid. But one really nice thing I stumbled upon (in this nice blog called Gnuplot tricks) is using the "for" loop to plot a function n times:

f(x,i)=i*x
plot [-pi:pi] for [i=1:10] f(x,i)

Otherwise you'd have to plot each one of the lines. This way you only have to issue two or four commands (depending if you want a different pattern for a "minor grid").

We'll use the Mollweide projection parametric functions that we copied from Roberto's blog(the ones mentioned in my previous post). Now I almost lost my head trying to express these parametric expressions as normal functions so I could just write "plot y(x)" (the parametric ones depend on other variables and give you an expression of x,y pairs instead of a function y(x) ).

Enter the command: set parametric. This will allow you to do the same as with columns in a data file, which is to plot on function (y=f(t)) against another (x=(g(t))¹ .

So this is the code for a Mollweide grid:

set parametric
plot [-pi:pi] for [i=-5:5] mwx(pi*i/10,t),mwy(pi*i/10,t) with line linetype -1, \
for [i=-5:5] mwx(t/2,pi*i/5),mwy(t/2,pi*i/5) with line linetype -1
Note that we use "with linetype -1" for solid black lines and "with linetype 0" for dotted black lines. Gnuplot is programmed so that the simple way is to use predefined styles for lines/points/etc. However one can specify color with the somewhat obscured command "with lines linecolor rgb '#000000'" or abbreviated "w l lc rgb '#000000'".

Another very important thing to note is that the range of the dummy variable t is only set at the beginning of the plot command and cannot be issued multiple times (cannot be issued after the comma). I considered using multiplot for overriding this but it was a very bad idea when dealing with the map previously plotted.

Oh right, you'll probably want the map to be behind those lines, but the range of the plotted functions' dummy variable (t) must be issued right after the plot command, so in order to do the full plot of map and grid this is the final plot command:

plot [-pi:pi] "gnuplot.dat" using (mwx(bconv($2),lconv($1))):(mwy(bconv($2),lconv($1))):($3/1E7) with points palette, \
for [i=-2:2] mwx(pi*i/6,t),mwy(pi*i/6,t) w l lt 0,\
for [i=-3:3] mwx(t/2,pi*i/4),mwy(t/2,pi*i/4) w l lt 0, \
for [i=0:1] mwx(t/2,pi-2*pi*i),mwy(t/2,pi-2*pi*i) w l lt -1 lw 3, \
"grid-labels.dat" using (mwx($2/180*pi,$1/180*pi)):(mwy($2*pi/180,$1*pi/180)):3 with labels
I tried plotting the grid labels more elegantly but failed due to constrains in the system, so I ended up just plotting a data file that contained the coordinates and text for a label. Also note I decided to change the inner linetype to 0.


Here's the final result:


¹I tend to try in all possibilities to give a reference to what helped me, but in this case it was hours of droning with my favorite search engine until I stroke the right phrase that lead me to a gnuplot faq page that I didn't quite find explanatory but gave me the clue to search the word "parametric" (hoping for the manual but falling on this lanl webpage I keep bumping into).

No comments:

Post a Comment