gnuplot draw 3d level curve

Profile plots

Maps - Contour plots with labels

So, yous have always wondered how on Earth one can make a real map with gnuplot. Well, at that place is a elementary and a non-so-simple style to this. Get-go, permit us encounter the uncomplicated way. Since it is simple, this method won't take one of the features, isoline labelling, that the 2d one has. As we become along, the map will become more and more complicated, but I hope that I set up the right stride, and it volition exist piece of cake to follow.

A map is zip merely a colour-coded 3D plot, with the isolines attached to it. We will produce a simple map using the function

sin(i.3*10)*cos(0.ix*y)+cos(.8*10)*sin(one.9*y)+cos(y*.ii*10)        

I don't call up that this function has whatever particular meaning, merely information technology looks quite all right, at least, equally far as maps and isolines are concerned. If you have a matrix to plot, y'all can replace this function with that file. In principle, we could plot both the color-coded map and the isolines from gnuplot, merely we volition have much greater flexibility, if we first directly the plots to a file, and so call the data from those files. One of the advantages of doing this is that in this way, we can make sure that the various plots take the aforementioned size. This requires a pocket-sized overhead in terms of scripting, namely, we accept got to issue the command

set tabular array 'something.dat' splot something unset table        

While this might appear superfluous, there are good reasons to practise this. If nosotros plot our function through the file something.dat, and so we tin employ the with image modifier of the plot command, and this means that the plot will exist of the same size every bit would a normal 2D plot. Otherwise, if nosotros utilise

set pm3d map splot something with pm3d        

the plot will really be a bit smaller. The reason behind this is that in a 3D plot, we have to have some space for the z axis, and fifty-fifty if we drop it in the map view, the space-holder for the z axis is still there, therefore, gnuplot makes the whole plot a bit smaller. If, however, nosotros plot the map through a file, we tin can utilise plot, in splot'southward stead, therefore, the z axis volition not appear anywhere in the processing of the plot.

Later this interlude, allow us see our first version of the map!

reset f(x,y)=sin(1.3*10)*cos(.9*y)+cos(.8*x)*sin(i.9*y)+cos(y*.two*ten) set xrange [-v:5] prepare yrange [-v:5] ready isosample 250, 250 set table 'test.dat' splot f(x,y) unset tabular array  set up contour base set cntrparam level incremental -3, 0.5, 3 unset surface set tabular array 'cont.dat' splot f(x,y) unset table  reset set xrange [-5:5] gear up yrange [-5:5] unset key set palette rgbformulae 33,13,10 p 'exam.dat' with image, 'cont.dat' w l lt -1 lw 1.5          

In the first couple of lines, nosotros plot the actual function into a file, called test.dat. There volition be some 25000 data points in this file, for in that location are 100 samples (default), and 250 isosamples. Having written these points into a file, we plot the contour. We just happen to know that the value of f(x,y) is between -3 and iii, so we set up the contour levels at -3, -2.5...ii.five, three. When we are washed with all this, we merely reset our plot, set the x and yrange, specify the palette that we desire to employ with the colouring, and phone call the plot command. For the bodily data points, we use the with epitome modifier, while for the contours, nosotros increment the linewidth to ane.5, instead of using the default value of 1. We, thus, have just produced the post-obit image.

contour1.png

Now, this was sort of standard, but the question inevitably comes up, whether nosotros could do something more with this. When ane has contour lines, i wants to label them, I presume. Petr Mikulik has a gawk script that will exercise this, in detail, it will place the appropriate labels next to the contour lines. I volition discuss another approach here. The main difference with Petr Mikulik'southward method is that here we will put the labels on the profile lines, with some white infinite, of grade.

Start, information technology is quite instructive to look at the file containing the contour lines. In gild not to cobble the plot, we will restrict information technology to the range [-v:0] (x) and [ii:5], simply information technology is really only for the sake of simplicity. With this modification, the file should read every bit

#Surface 0 of ane surfaces \n # Contour 0, label:        2 -0.482969  3.59036  2 -0.505051  3.58024  2 -0.509852  3.57831  ii -0.539895  3.56627  ii -0.555556  3.55994  2 -0.572136  3.55422  ii ...  # Contour 1, label:      1.five -i.11111  4.57693  ane.5 -i.10874  iv.57831  1.5 -ane.0877  four.59036  one.v -1.06617  4.60241  ane.5 -i.06061  4.60546  one.5 -i.04273  4.61446  1.5 ...          

What this means is that the 0th contour line is drawn at z=2, and and then the (x,y,z) values are listed. Of form, since we know that this particular line is at z=two, the last coordinate doesn't play any role, simply it is listed even so. When nosotros plot this file, sequent (x,y) points will exist connected by a straight line segment. The next contour is at 1.5 etc. It might happen that one contour line is made upward of several blocks, both for technical, and fundamental reasons. The technical reason is gnuplot'southward inner procedure of calculating the an isoline, while the key is only that at that place might be several disconnected regions with the aforementioned isolevel. Anyway, if there are several blocks, they are separated by a blank line within the aforementioned contour.

In order to create the labels and the white spaces for them, nosotros will use the post-obit short script:

#!/bin/bash gawk -v d=$2 -v w=$iii -five os=$4 'function abs(ten) { return (ten>=0?ten:-x) }     {             if($0~/# Contour/) nr=0             if(nr==int(os+w/2) && d==0) {i++; a[i]=$ane; b[i]=$2; c[i]=$three;}             if(abs(nr-bone-w/ii)>due west/two && d==1) print $0             nr++     }     End {   if(d==0) {                     for(j=1;j<=i;j++)                     printf "set label %d \"g\" at %thou, %m eye front\n", j, c[j], a[j], b[j]             }     }' $one        

This script operates on the information file of contour lines that we had before, and merely takes out a couple of points of the contours, while keeping 1 of the coordinates as the position of the labels. You can change the length of the white space by setting the westward (width) statement, while the position of the white space can be modified past changing the os (first) argument. The showtime argument, d (decision), determines what we want to do with the script: make the labels, or tweak the input file. At present, we tin can phone call the script from our gnuplot script as follows:

reset set up xrange [-v:0] fix yrange [two:5] set isosample 150, 150 set table 'test.dat' splot sin(1.3*x)*cos(.9*y)+cos(.eight*10)*sin(1.9*y)+cos(y*.2*x) unset table prepare cont base set cntrparam level incremental -iii, 0.v, 3 unset surf prepare table 'cont.dat' splot sin(1.3*x)*cos(0.9*y)+cos(.8*x)*sin(i.ix*y)+cos(y*.ii*x) unset table reset set xrange [-5:0] set yrange [2:v] unset cardinal set palette rgbformulae 33,13,10 l '<./cont.sh cont.dat 0 fifteen 0' p 'examination.dat' w ima, '<./cont.sh cont.dat 1 15 0' w fifty lt -1 lw 1.5        

Running the script results in the following figure

contour2.png

There are two more twists that we could add to the figures above. One is that the labels can be rotated in such a way that they are parallel to the curves. This we can easily achieve by calculation ii more lines to our script higher up: we take the first and last dropped coordinate, and calculate the angle that that line segment would make with the horizontal. Using this angle, we rotate the labels accordingly. With this modification, the script now becomes

#!/bin/bash  gawk -v d=$2 -five due west=$three -v os=$4 'role abs(x) { return (x>=0?x:-10) }     {             if($0~/# Contour/) nr=0             if(nr==int(bone+due west/2) && d==0) {a[i]=$1; b[i]=$two; c[i]=$3;}             if(nr==int(bone+w/ii)-1 && d==0) {i++; 10 = $1; y = $2;}             if(nr==int(os+w/two)+1 && d==0) r[i]= 180.0*atan2(y-$ii, 10-$1)/3.fourteen             if(abs(nr-os-due west/two)>w/2 && d==1) print $0             nr++     }     Finish {   if(d==0) {                     for(j=one;j<=i;j++)                     printf "set characterization %d \"%grand\" at %g, %g centre front rotate by %d\n", j, c[j], a[j], b[j], r[j]             }     }' $1          

and the resulting graph is shown here:

contour4.png

Note that the only difference between this and the previous script is the following two lines

if(nr==int(os+w/2)-1 && d==0) {i++; x = $1; y = $ii;} if(nr==int(os+west/2)+ane && d==0) r[i]= 180.0*atan2(y-$two, x-$1)/three.fourteen        

where nosotros calculate the advisable angles.

The second twist is that it might make estimation of the effigy easier, if the contours are coloured, as are the corresponding labels. We can employ the script above with some minor modification. The key is to use the alphabetize modifier. Think that the contours are rendered in blocks, and with the help of the index keyword, nosotros can specify which block we want to plot. We, therefore, modify our script every bit follows:

#!/bin/fustigate  gawk -v d=$two -v westward=$3 -v os=$four 'role abs(x) { render (ten>=0?x:-x) }    {            if($0~/# Contour/) nr=0            if(nr==int(bone+w/two) && (d\%two)==0) {a[i]=$1; b[i]=$2; c[i]=$3;}            if(nr==int(os+w/2)-ane && (d\%2)==0) {i++; x = $i; y = $2;}            if(nr==int(os+w/2)+1 && (d\%2)==0) r[i]= 180.0*atan2(y-$ii, x-$1)            if(abs(nr-os-w/2)>w/ii && (d\%two)==ane) print $0            nr++    }    Cease {   if(d==0) {                    for(j=1;j<=i;j++)                    printf "fix characterization %d \"%g\" at %thou, %g centre front rotate by %d tc lt %d \due north", j, c[j], a[j], b[j], r[j], j            }            if(d==ii) {                    printf "plot \"test.dat\" w ima, \"cont.plt\" index 0 w fifty lt i,\\\due north"                    for(j=2;j<i;j++) printf "\"\" index %d w l lt %d,\\\n", j-one, j                    printf "\"\" alphabetize %d w l lt %d\north", i-1, i            }    }' $1          

Calling the script produces the following graph:

contour5.png

Note that we had to phone call plot through a new temporary file, cont.plt, which should be produced by redirecting the output of

cont5.sh 2 15 0 > cont.plt        

by Zoltán Vörös © 2009

taylorayed1969.blogspot.com

Source: http://www.phyast.pitt.edu/~zov1/gnuplot/html/contour.html

0 Response to "gnuplot draw 3d level curve"

Enviar um comentário

Iklan Atas Artikel

Iklan Tengah Artikel 1

Iklan Tengah Artikel 2

Iklan Bawah Artikel