Search code examples
3dlatexgnuplottransparency

Gnuplot overlay transparent 3D surface and plane in different colour


I'd like to produce a figure similar to this one Mathematica figure

in gnuplot. So there is a line on the surface tracing through slightly transparent planes. The dots aren't very important. For my workflow, I'm using gnuplottex. So far, I'm here: Gnuplot figure

That's my code

\documentclass{standalone}

\newif\ifwindows
\IfFileExists{/dev/null}{\windowsfalse}{\windowstrue}
\ifwindows
\usepackage[miktex,cleanup]{gnuplottex}
\else
\usepackage[]{gnuplottex}
\fi

\begin{document}
%\begin{gnuplot}[terminal=pslatex, terminaloptions={auxfile color dashed rounded dl 1. lw 1. size 12cm, 9cm}]
\begin{gnuplot}[terminal=cairolatex, terminaloptions={pdf color dashed rounded dl 1. lw 1. size 12cm, 9cm}]
    set grid front
    set format x '%g'
    set format y '%g'
    set xr [0. : 5.]
    set yr [0. : 5.]

    f(x, y) = \
    .5 * log(1. + 4. * x * (sqrt(y) + sqrt(1. + y))**2) / log(2.)
    xopt(x) = \
    (x * (1. + x)) / (1. + 2. * x)
    yopt(x) = \
    x**2 / (1. + 2. * x)

    set isosamples 75
    set samples 80
    set contour base
    set cntrparam levels incremental .5, .5
    set cntrparam levels 12
    set cntrlabel onecolor
    set style line 1 lc rgb "#000000"
    set style increment userstyle
    set style fill transparent solid 0.6
    set pm3d at s scansforward implicit nohidden3d

    set parametric
    set ur [0. : 5.]
    set vr [0. : 5.]

    splot \
    u, v, f(u, v) t '' w pm3d, \
    '++' u (xopt($1 * 1.85)):(yopt($1 * 1.85)):(f(xopt($1 * 1.85), yopt($1 * 1.85))) t '' w l lc 1, \
    u, 1. - u, v t '' w surface
  \end{gnuplot}
\end{document}

I've tried both the pslatex and cairolatex terminal for ps and, resp., pdf output. The issue is that I'd like to have the grid removed from the plane and coloured in a monotone (or at least different) colour. The grid can be removed by nosurface, but then I'm still left with a plane in all colours. PS: I'm aware that transparency doesn't go very well with ps, but in this example the surface with the pslatex terminal actually works quite well.


Solution

  • Using a multiplot did the trick:

    enter image description here

    \documentclass{standalone}
    
    \newif\ifwindows
    \IfFileExists{/dev/null}{\windowsfalse}{\windowstrue}
    \ifwindows
    \usepackage[miktex,cleanup]{gnuplottex}
    \else
    \usepackage[]{gnuplottex}
    \fi
    
    \begin{document}
    %\begin{gnuplot}[terminal=pslatex, terminaloptions={auxfile color dashed rounded dl 1. lw 1. size 12cm, 9cm}]
    \begin{gnuplot}[terminal=cairolatex, terminaloptions={pdf color dashed rounded dl 1. lw 1. size 12cm, 9cm}]
        set format x '%g'
        set format y '%g'
        set grid front
    
        f(x, y) = \
        .5 * log(1. + 4. * x * (sqrt(y) + sqrt(1. + y))**2) / log(2.)
        xopt(x) = \
        (x * (1. + x)) / (1. + 2. * x)
        yopt(x) = \
        x**2 / (1. + 2. * x)
    
        set isosamples 75
        set samples 80
        set contour base
        set cntrparam levels incremental .5, .5
        set cntrparam levels 12
        set cntrlabel onecolor
        set style line 1 lc rgb "#000000"
        set style increment userstyle
        set style fill transparent solid 0.6
        set pm3d at s scansforward implicit nohidden3d
    
        set xr [0. : 5.]
        set yr [0. : 5.]
        set parametric
        set ur [0. : 5.]
        set vr [0. : 5.]
    
        set multiplot
    
        splot u, v, f(u, v) t '' w pm3d
    
        unset tics
        unset border
        unset xlabel
        unset ylabel
        unset zlabel
        unset colorbox
    
        set palette defined ( 0 "black", 1 "black" )
        set style fill transparent solid 0.3
    
        set label 1 ' ' center at first xopt(1.), yopt(1.), f(xopt(1.), yopt(1.)) point pt 7 ps .5
        set label 2 ' ' center at first xopt(3.), yopt(3.), f(xopt(3.), yopt(3.)) point pt 7 ps .5
        set label 3 ' ' center at first xopt(5.), yopt(5.), f(xopt(5.), yopt(5.)) point pt 7 ps .5
        set label 4 ' ' center at first xopt(7.), yopt(7.), f(xopt(7.), yopt(7.)) point pt 7 ps .5
    
        splot \
        '++' u (xopt($1 * 1.8)):(yopt($1 * 1.8)):(f(xopt($1 * 1.8), yopt($1 * 1.8))) t '' w l lc 1, \
        for [i = 1:8:2] u, i - u, v t '' w surface nosurface
    
        unset multiplot
      \end{gnuplot}
    \end{document}