Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Gnuplot multiplot axes, isolines in one direction

Tags:

gnuplot

I tried reproducing an image showing intensity distribution of transverse electromagnetic (TEM) modes with parameters m and n. I have used a 4x4 multiplot matrix of surface plots. The result is satisfying for me. Just for the sake of completeness:

  1. How would you add the axes instead of having a separate title for each single plot?
  2. Is there a way to display the isolines on the surface only in one direction like in the original image?
  3. The original author has left out the lower part of the multiplot to underline the symmetry. I am not sure whether this really makes the point clear. Should I rather just show the full matrix or can you think of a better way?

template image

Solution

Thanks everybody. With your suggestions I now have the following picture:

current state with scaling axes and colors

Which is output from the Qt terminal for the following code:

m=n=3           # max. 3
THETA=2.5

set hidden3d trianglepattern 2 
set isosamples 50
set xrange [-THETA:THETA]
set yrange [-THETA:THETA]
set view 70,55,,.5
unset border
unset key
unset tics

H0(x)=1
H1(x)=2*x
H2(x)=4*x**2-2
H3(x)=8*x**3-12*x

set multiplot layout n+1,m+1 upwards margins .14,.9,.14,.9 spacing .05 \ 
        title 'Intensitätsverteilungen der Laguerre-Gauß-Moden' font ",16"
do for [i=0:n] for [j=0:m] { 
        eval sprintf("splot (H%d(sqrt(2)*y)*exp(-y**2))**2\
                          * (H%d(sqrt(2)*x)*exp(-x**2))**2\
                                with lines lc %d", i, j, abs(i-j)+1)
}
set origin 0,0
set size 1,1
unset margins
set title ' '
set arrow from 0,-.5 to graph 1,0
set arrow from -.5,0 to graph 0,1
set label at .5, .5 "dreh-\nsymmetrisch" center rotate by -37
set arrow from .7,0 to .1,.6
set tics out nomirror
set xtics 0, 1, n
set ytics 0, 1, m
set xrange [-.5:n+.5]
set yrange [-.5:m+.5]
set xlabel offset graph .5,0 "n"
set ylabel offset graph 0,.5 "m" norotate
plot NaN
unset multiplot
  1. Instead of adding the axes manually, I plotted an aptly scaled 2D plot atop. Thus the axes scale for parameters m and n other than 3. For supporting higher orders one has to add according Hermite polynomials Hn(x); n=1, 2, 3, ... and may need to adjust the margins of the multiplot.
  2. Supplying set hidden3d trianglepattern 2 proved to be the easiest way to have the isolines display in only one direction.
  3. The colors should help making out pairs of rotational symmetric figures. One may argue the aesthetics, but the message hopefully gets conveyed.
like image 616
Heinz Schenk Avatar asked Oct 17 '25 19:10

Heinz Schenk


2 Answers

Try the following and tweak it to your needs. There is certainly room for improvements.

to 1. use some margins for the multiplot and draw the lines via arrows and labels which need to be tuned.

to 2. put the data into a datablock and plot it with zerrorfill (see help zerrorfill)

to 3. I would say that is a matter of taste. Why does the author only show TEM01, to just have one example? Why not showing all?

Code:

### isolines only in one direction
reset session
# set term wxt size 900,950   # or some other terminal and sizes

unset key
unset tics
set border 0
set view 55,55,1.0,0.5

set style fill solid 0.0
do for [i=1:99] {
    set linetype i lw 0.5 lc rgb "black"
}

THETA=2.5
set xrange [-THETA:THETA]
set yrange [-THETA:THETA]

H0(x)=1
H1(x)=2*x
H2(x)=4*x**2-2
H3(x)=8*x**3-12*x

m=n=3
set multiplot layout n+1,m+1 upwards \
    title 'Intensitätsverteilungen der Laguerre-Gauß-Moden' \
    margins screen 0.1, screen 0.95, screen 0.15, screen 0.9

    do for [i=0:n] for [j=0:m] {
    #    if (i >= j || i == 0 && j == 1) {   # uncommenting this line skips TEM02,03,12,13,23 
            # eval sprintf("set title 'TEM_{%d%d}'", i, j)    # uncomment to show title
             eval sprintf("f(x,y) = (H%d(sqrt(2)*y)*exp(-y**2))**2 \
                              * (H%d(sqrt(2)*x)*exp(-x**2))**2", i, j)
            # data to datablock
            set print $Data
                c=20.0
                do for [iii=-c:c] {
                    do for [jjj=-c:c] {
                        x=iii/c*THETA
                        y=jjj/c*THETA
                        print sprintf("%g %g %g",x,y,f(x,y))
                    }
                print ""  # add empty line
                print ""  # add empty line
                }
            set print
            splot $Data using 1:2:3:(0):3 with zerrorfill 

    #    } else { set multiplot next }      # uncommenting this line skips TEM02,03,12,13,23 

    }
    unset title

    # arrows and labels 
    A1x0=0.16; A1x1=0.95; A1y=0.05;  A1grid=0.225
    A2x=0.05;  A2y0=0.20; A2y1=0.95; A2grid=0.20
    TicL=0.01
    set arrow 1 from screen A1x0,A1y to screen A1x1,A1y lw 3
    set label 1 "n" at screen A1x1,A1y offset 0,-1 font ",14"
    set arrow 2 from screen A2x,A2y0 to screen A2x,A2y1 lw 3
    set label 2 "m" at screen A2x,A2y1 offset -4,0 font ",14"
    do for [i=0:3] {
        set label i+3 sprintf("%d",i) at screen A1x0+i*A1grid,A1y offset -0.7,-1.5 font ",14"
        set arrow i+3 from screen A1x0+i*A1grid,A1y to screen A1x0+i*A1grid,A1y-TicL lw 2 nohead
        set label i+7 sprintf("%d",i) at screen A2x,A2y0+i*A2grid offset -4,0 font ",14"
        set arrow i+7 from screen A2x,A2y0+i*A2grid to screen A2x-TicL,A2y0+i*A2grid lw 2nohead
    }
    plot NaN   # plot nothing but to add the arrows and labels
unset multiplot
### end of code

Result:

enter image description here

like image 153
theozh Avatar answered Oct 22 '25 00:10

theozh


Regarding your point 2 (isolines in one direction), I found fence plot with zerrorfill can do it:

w = 2.5
set xrange [-w:w]
set yrange [-w:w]
set view 55,55,1.
set ticslevel 0

H1(x) = 2*x
H2(x) = 4*x**2-2
f(x,y) = (H2(sqrt(2)*y)*exp(-y**2))**2\
                          * (H1(sqrt(2)*x)*exp(-x**2))**2

splot for [i=-25:25] '+' us (y=i/10.):1:(z=f(x,y)):(0):(z) w zerrorfill  fc "white" lc "black" t ""

Less nice, was my first try:

set hidden3d
w = 2.5
set xrange [-w:w]
set yrange [-w:w]
set view 55,55,1.
set ticslevel 0

set iso 100,200
set palette defined (0 "white", 1 "black")
set cbrange[0:1]

H1(x) = 2*x
H2(x) = 4*x**2-2
f(x,y) = (H2(sqrt(2)*y)*exp(-y**2))**2\
                          * (H1(sqrt(2)*x)*exp(-x**2))**2

splot '++' us 1:2:(f(x,y)-0.05):(0) w l palette, i=0,\
      "++" us 1:2:(i=i+1, f(x,y)/(i%2==0)):(1) w l palette

enter image description here The first plot object takes care of the hidden part and is just white. The second plot object has black lines; the division with (i%2==0) creates nans for every second line, yielding suppressed lines in one direction.

like image 32
Friedrich Avatar answered Oct 21 '25 23:10

Friedrich



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!