6

Based on 3D normal diffusion I want to draw the idea the normal distribution is flattening over time, but with a drift.

1 - As you can see in MWE below, the orange normal distribution seems to be cut at its base. Why so ? I actually try to have a "shadow diffusion" along the black line but due to the problem above, my distribution is cut at its basis.

2 - I also try to fill with light opacity the half distribution on the red side of the distribution. A simple does not seem to work.

3 - The junction on top of the distribution seems to have a tiny white gap.

enter image description here

\documentclass[border =2mm]{standalone}

\usepackage{tikz}
\usepackage{tikz-3dplot}
\usepackage{xintexpr}
\usetikzlibrary{decorations.pathmorphing,bending} 
\usetikzlibrary{3d}

\usepackage{pgfplots, pgfplotstable}
%\pgfplotsset{compat=1.13} % for better axis label placement
\pgfplotsset{compat=1.15}
\usepgfplotslibrary{fillbetween}
\usepgfplotslibrary{groupplots}
\usepackage{graphicx}% Allows   ding images

\begin{document}

\def\Fwd{1.5}
\def\Z{30}
\makeatletter 
\pgfdeclareplotmark{dot} {\fill circle [x radius=0.02, y radius=0.08];}
\makeatother       


\begin{tikzpicture}%[ % Define Normal Probability Function

    \tikzset{
        declare function={ 
            normal(\x,\m,\s) = 1/(2*\s*sqrt(pi))*exp(-(\x-\m)^2/(2*\s^2));
            invgauss(\a,\b) = sqrt(-2*ln(\a))*cos(deg(2*pi*\b));
            forward(\a) = {\Fwd*(\a-0.5)+3};
            call(\a,\b) = 0.35*max(\a-\b,0); %Facteur pour avoir un graphe de call plus haut
    }}

    \makeatletter
    \pgfdeclareplotmark{dot}
    {\fill circle [x radius=0.02, y radius=0.08];}
    \makeatother       

    \tikzset{
        distrib/.style={blue, ultra thick,opacity=0.40},
        distribLeft/.style={distrib,red},
        diffusion/.style={gray!50, only marks, mark=dot, mark layer=like plot, samples=200, domain=0.1:3.5, on layer=axis background},
        Forward/.style={samples=2,domain=0:3,thick,red},
        CallPayOff/.style={samples=200,cyan!50!black,thick}
    }                      


    \begin{axis}[
            domain=0:8,
            zmin=0, zmax=0.5,
            ymin=0, ymax=8,
            xmin=0, xmax=3,
            samples=200,
            samples y=0,
            view={60}{30},
            axis lines=middle,
            enlarge y limits=true,
            xtick={0.5,1.5,2.5},
            xmajorgrids,
            ytick=\empty,
            xticklabels={$t_1$, $t_2$, $t_3$},
            ztick=\empty,
            xlabel=$time$, xlabel style={at={(rel axis cs:1,0,0)}, anchor=west,font=\small},
            ylabel=$S$, ylabel style={at={(rel axis cs:0,1,0)}, anchor=south west,font=\small},
            zlabel=Probability density, zlabel style={at={(rel axis cs:0,0,0.5)},font=\small, rotate=90, anchor=south},
            set layers, mark=cube
        ]

        \addplot3 [gray!50, only marks, mark=dot, mark layer=like plot, samples=200, domain=0.1:2.9, on layer=axis background] (x, {1.5*(x-0.5)+3+invgauss(rnd,rnd)*x}, 0);
        \addplot3 [Forward] (x, {1.5*(x-0.5)+3}, 0);
        %Forward flat, le spot
        \addplot3 [Forward,black] (x, {forward(0)}, 0);
        %Distributions centrées sur le forward
        \addplot3 [distrib,domain=forward(0.5):10] (0.5, x, {normal(x, forward(0.5), 0.75)});
        \addplot3 [distrib,domain=forward(1.5):10] (1.5, x, {normal(x, forward(1.5), 1.0)});
        \addplot3 [distrib,domain=forward(2.5):10] (2.5, x, {normal(x, forward(2.5), 1.25)});

        %Distributions centrées sur le forward
        \addplot3 [distribLeft,domain=0:forward(0.5)] (0.5, x, {normal(x, forward(0.5), 0.75)});
        \addplot3 [distribLeft,domain=0:forward(1.5)] (1.5, x, {normal(x, forward(1.5), 1.0)});
        \addplot3 [distribLeft,domain=0:forward(2.5)] (2.5, x, {normal(x, forward(2.5), 1.25)});


        \pgfplotsextra{
            \begin{pgfonlayer}{axis background}
                \draw [gray, on layer=axis background] 
                (0.5, {forward(0)}, 0)   -- (0.5, {forward(0)}, {normal(0,0,0.75)}) (0.5,0,0) -- (0.5,10,0)
                (0.5, {forward(0.5)}, 0)   -- (0.5, {forward(0.5)}, {normal(0,0,0.75)}) (0.5,0,0) -- (0.5,10,0)
                (1.5, {forward(1.5)}, 0) -- (1.5, {forward(1.5)},   {normal(0,0,1)})    (1.5,0,0) -- (1.5,10,0)
                (2.5, {forward(2.5)}, 0)   -- (2.5, {forward(2.5)}, {normal(0,0,1.25)})     (2.5,0,0) -- (2.5,10,0);
            \end{pgfonlayer}
        }

        %Distributions centrées sur 100
        \addplot3 [distrib,fill=orange,domain=0:10,orange] (0.5, x, {normal(x, forward(0), 0.75)});
        %mark=*, 
        \draw plot [mark=ball,mark size=2, ball color=blue] coordinates{(0, {forward(0)}, 0)}; 
        \draw plot [mark=ball, mark size=2, ball color=red] coordinates{(0.5, {forward(0.5)}, 0)}; 
        \draw plot [mark=ball, mark size=2, ball color=red] coordinates{(1.5, {forward(1.5)}, 0)}; 
        \draw plot [mark=ball, mark size=2, ball color=red] coordinates{(2.5, {forward(2.5)}, 0)}; 

        \coordinate[label=\tiny{Forward}] (B1) at (3,{forward(2.5)+0.2},0);
        \coordinate[label=\tiny{Spot}] (B1) at (3.1,0.6,0);


    \end{axis}
\end{tikzpicture}

\end{document}

And here is my updated version with conditions on what to display. Merci Schrodinger !

\documentclass[border=2mm]{standalone}
\usepackage{pgfplots}
\usepackage{amssymb}
\pgfplotsset{compat=1.16}

\def\Fwd{1.1}
\def\Sig{0.4}
\def\Spot{1}
\def\Forward{1}
\def\PointDiffusion{0}

\pgfdeclareplotmark{dot}{\fill circle [x radius=0.02, y radius=0.08];}

\begin{document}

\begin{tikzpicture}[
        declare function={ 
            normal(\x,\m,\s) = 1/(2*\s*sqrt(pi))*exp(-(\x-\m)^2/(2*\s^2));
            invgauss(\a,\b) = sqrt(-2*ln(\a))*cos(deg(2*pi*\b));
            forward(\a) = {\Fwd*(\a-0.5)+3};
            call(\a,\b) = 0.35*max(\a-\b,0); %Facteur pour avoir un graphe de call plus haut
        },
        distrib/.style={blue!40, ultra thick},
        distribLeft/.style={distrib,red!40},
        distribSpot/.style={distrib,domain=0:5,orange!50,thin},
        diffusion/.style={gray!50, only marks, mark=dot, mark layer=like plot, samples=200, domain=0.1:3.5, on layer=axis background},
        Forward/.style={samples=2,domain=0:3,thick,red},
        CallPayOff/.style={samples=200,cyan!50!black,thick}
    ]
    \begin{axis}[
            domain=0:8,
            zmin=0, zmax=0.75,
            ymin=0, ymax=8,
            xmin=0, xmax=3,
            samples=200,
            samples y=0,
            view={60}{30},
            axis lines=middle,
            enlarge y limits=true,
            xtick={0.5,1.5,2.5},
            xmajorgrids,
            ytick=\empty,
            xticklabels={$t_1$, $t_2$, $t_3$},
            ztick=\empty,
            xlabel=$time$, xlabel style={at={(rel axis cs:1,0,0)}, anchor=west,font=\small},
            ylabel=$S$, ylabel style={at={(rel axis cs:0,1,0)}, anchor=south west,font=\small},
            zlabel=$\mathbb{P}$ density, zlabel style={at={(rel axis cs:0,0,0.75)},font=\small, rotate=90, anchor=south},
            set layers=standard,% mark=cube
        ]
        % circles on the gound
        \if 1\Spot
            %Forward flat, le spot
            \addplot3 [Forward,orange] (x, {forward(0)}, 0);
            \if 1\PointDiffusion
                \addplot3 [orange!50, only marks, mark=dot, mark layer=like plot, on layer=axis background,samples=300, domain=0.1:2.9] 
                (x,{forward(0)+invgauss(rnd,rnd)*x}, 0);
            \fi
        \fi
        \if 1\Forward
            \addplot3 [Forward] (x, {forward(x)}, 0);
            \if 1\PointDiffusion
                \addplot3 [gray!50, only marks, mark=dot, mark layer=like plot, on layer=axis background,samples=200, domain=0.1:2.9] 
                (x,{forward(x)+invgauss(rnd,rnd)*x}, 0);
            \fi
        \fi     

        %
        %Distributions centrées sur 100
        \addplot3 [distrib,domain=0:10,fill=orange,fill opacity=0.3,draw=none] 
        (0, x, {normal(x, forward(0), \Sig)}) -- (0, 10, 0) -- (0, 0, 0) ;
        \addplot3 [only marks,mark=ball,mark size=2,mark options={color=orange,ball color=orange,line width=0pt}] coordinates {(0, {forward(0)}, 0)}; 
        \addplot3 [distribSpot,ultra thick] (0, x, {normal(x, forward(0), \Sig)});

        %Distributions centrées sur le spot
        %Distributions centrées sur le forward
        \pgfplotsinvokeforeach{1,2,3}{
            \if 1\Spot
                \addplot3 [distribSpot] (-0.5+#1, x, {normal(x, forward(0), \Sig+0.25*#1)});
            \fi
            \if 1\Forward
                \addplot3 [distrib,domain=10:{forward(-0.5+#1)-0.01}] 
                (-0.5+#1, x, {normal(x,   {forward(-0.5+#1)}, \Sig+0.25*#1)}) ;
                \addplot3 [fill=red,fill opacity=0.2,domain=0:{forward(-0.5+#1)}] 
                (-0.5+#1, x, {normal(x, {forward(-0.5+#1)},  \Sig+0.25*#1)})
                -- (-0.5+#1, {forward(-0.5+#1)},0)  -- (-0.5+#1, 0,0); 
                \addplot3 [distribLeft,domain=0:{forward(-0.5+#1)}] 
                (-0.5+#1, x, {normal(x, {forward(-0.5+#1)},  \Sig+0.25*#1)}); 
                \draw[gray] (-0.5+#1, {forward(0)}, 0) -- (-0.5+#1,10,0)
                (-0.5+#1,{forward(-0.5+#1)},0) --
                (-0.5+#1,{forward(-0.5+#1)},{normal({forward(-0.5+#1)}, {forward(-0.5+#1)},  \Sig+0.25*#1)});  
                \addplot3 [only marks,mark=ball,mark size=2,mark
                options={color=red,ball color=red,line width=0pt}] coordinates
                {(-0.5+#1, {forward(-0.5+#1)}, 0)}; 
            \fi       
        }
        \path (3, {1.5*(3-0.5)+3}, 0) coordinate (F);
        \coordinate[label={[font=\tiny]Spot}] (B2) at (3.1,0.6,0);
    \end{axis}
    \path (F) node[below,font=\tiny] {Forward};
\end{tikzpicture}
\end{document}

enter image description here

  • 5
    The result of your draw...is very beautiful. My compliments. – Sebastiano Mar 14 at 21:38
7

Here is something that addresses your points. To arrive there, I stripped off unnecessary packages and definitions. I decided to fill "brute force" since the layers make 3d ordering hard to achieve with the fillbetween library. As for the latter, I reordered the plots. To understand why, notice that pgfplots does some ordering within a give \addplot3 but does not order the plots relative to each other.

\documentclass[border=2mm]{standalone}
\usepackage{pgfplots}
\pgfplotsset{compat=1.16}
%\usepgfplotslibrary{fillbetween}

\begin{document}

\begin{tikzpicture}[
        declare function={ 
            normal(\x,\m,\s) = 1/(2*\s*sqrt(pi))*exp(-(\x-\m)^2/(2*\s^2));
            invgauss(\a,\b) = sqrt(-2*ln(\a))*cos(deg(2*pi*\b));
            forward(\a) = {\Fwd*(\a-0.5)+3};
            call(\a,\b) = 0.35*max(\a-\b,0); %Facteur pour avoir un graphe de call plus haut
        },
        distrib/.style={blue!40, ultra thick},
        distribLeft/.style={distrib,red!40},
        diffusion/.style={gray!50, only marks, mark=dot, mark layer=like plot, samples=200, domain=0.1:3.5, on layer=axis background},
        Forward/.style={samples=2,domain=0:3,thick,red},
        CallPayOff/.style={samples=200,cyan!50!black,thick}
        ]
    \def\Fwd{1.5}
    \pgfdeclareplotmark{dot}{\fill circle [x radius=0.02, y radius=0.08];}
    \begin{axis}[
            domain=0:8,
            zmin=0, zmax=0.5,
            ymin=0, ymax=8,
            xmin=0, xmax=3,
            samples=200,
            samples y=0,
            view={60}{30},
            axis lines=middle,
            enlarge y limits=true,
            xtick={0.5,1.5,2.5},
            xmajorgrids,
            ytick=\empty,
            xticklabels={$t_1$, $t_2$, $t_3$},
            ztick=\empty,
            xlabel=$time$, xlabel style={at={(rel axis cs:1,0,0)}, anchor=west,font=\small},
            ylabel=$S$, ylabel style={at={(rel axis cs:0,1,0)}, anchor=south west,font=\small},
            zlabel=Probability density, zlabel style={at={(rel axis cs:0,0,0.5)},font=\small, rotate=90, anchor=south},
            set layers=standard,% mark=cube
        ]
        % circles on the gound
        \addplot3 [gray!50, only marks, mark=dot, mark layer=like plot, 
            on layer=axis background,samples=200, domain=0.1:2.9] (x,
            {1.5*(x-0.5)+3+invgauss(rnd,rnd)*x}, 0);
        \addplot3 [Forward] (x, {1.5*(x-0.5)+3}, 0);
        %Forward flat, le spot
        \addplot3 [Forward,black] (x, {forward(0)}, 0);
        %
        %Distributions centrées sur 100
        \addplot3 [distrib,domain=0:10,fill=orange,fill opacity=0.4,draw=none] 
            (0.5, x, {normal(x, forward(0), 0.75)}) -- 
            (0.5, 10, 0) -- (0.5, 0, 0) ;
        \addplot3 [distrib,domain=0:10,orange] (0.5, x, {normal(x, forward(0), 0.75)});
        \addplot3 [only marks,mark=ball,mark size=2,mark size=2,mark
          options={color=red,line width=0pt}] coordinates {(0, {forward(0)}, 0)}; 
        %Distributions centrées sur le forward
        \pgfplotsinvokeforeach{1,2,3}{
          \addplot3 [distrib,domain=10:{forward(-0.5+#1)-0.01}] 
              (-0.5+#1, x, {normal(x,   {forward(-0.5+#1)}, 0.5+0.25*#1)}) ;
          \addplot3 [fill=red,fill opacity=0.3,domain=0:{forward(-0.5+#1)}] 
              (-0.5+#1, x, {normal(x, {forward(-0.5+#1)},  0.5+0.25*#1)})
              -- (-0.5+#1, {forward(-0.5+#1)},0)  -- (-0.5+#1, 0,0); 
          \addplot3 [distribLeft,domain=0:{forward(-0.5+#1)}] 
              (-0.5+#1, x, {normal(x, {forward(-0.5+#1)},  0.5+0.25*#1)}); 
          \draw[gray] (-0.5+#1, {forward(0)}, 0) -- (-0.5+#1,10,0)
              (-0.5+#1,{forward(-0.5+#1)},0) --
              (-0.5+#1,{forward(-0.5+#1)},{normal({forward(-0.5+#1)}, {forward(-0.5+#1)},  0.5+0.25*#1)});  
          \addplot3 [only marks,mark=ball,mark size=2,mark
             options={color=red,line width=0pt}] coordinates
              {(-0.5+#1, {forward(-0.5+#1)}, 0)}; 
        }
% 
        \coordinate[label={[font=\tiny]Forward}] (B1) at (3,{forward(2.5)+0.2},0);
        \coordinate[label={[font=\tiny]Spot}] (B2) at (3.1,0.6,0);
    \end{axis}
\end{tikzpicture}

\end{document}

enter image description here

The result looks partly OK. However, there is one thing I could not make sense of: the orange plot and one of the blue-red ones seem to share the same time coordinate. Is this intended? To me the following looks better.

\documentclass[border=2mm]{standalone}
\usepackage{pgfplots}
\pgfplotsset{compat=1.16}
%\usepgfplotslibrary{fillbetween}

\begin{document}

\begin{tikzpicture}[
        declare function={ 
            normal(\x,\m,\s) = 1/(2*\s*sqrt(pi))*exp(-(\x-\m)^2/(2*\s^2));
            invgauss(\a,\b) = sqrt(-2*ln(\a))*cos(deg(2*pi*\b));
            forward(\a) = {\Fwd*(\a-0.5)+3};
            call(\a,\b) = 0.35*max(\a-\b,0); %Facteur pour avoir un graphe de call plus haut
        },
        distrib/.style={blue!40, ultra thick},
        distribLeft/.style={distrib,red!40},
        diffusion/.style={gray!50, only marks, mark=dot, mark layer=like plot, samples=200, domain=0.1:3.5, on layer=axis background},
        Forward/.style={samples=2,domain=0:3,thick,red},
        CallPayOff/.style={samples=200,cyan!50!black,thick}
        ]
    \def\Fwd{1.5}
    \pgfdeclareplotmark{dot}{\fill circle [x radius=0.02, y radius=0.08];}
    \begin{axis}[
            domain=0:8,
            zmin=0, zmax=0.75,
            ymin=0, ymax=8,
            xmin=0, xmax=3,
            samples=200,
            samples y=0,
            view={60}{30},
            axis lines=middle,
            enlarge y limits=true,
            xtick={0.5,1.5,2.5},
            xmajorgrids,
            ytick=\empty,
            xticklabels={$t_1$, $t_2$, $t_3$},
            ztick=\empty,
            xlabel=$time$, xlabel style={at={(rel axis cs:1,0,0)}, anchor=west,font=\small},
            ylabel=$S$, ylabel style={at={(rel axis cs:0,1,0)}, anchor=south west,font=\small},
            zlabel=Probability density, zlabel style={at={(rel axis cs:0,0,0.5)},font=\small, rotate=90, anchor=south},
            set layers=standard,% mark=cube
        ]
        % circles on the gound
        \addplot3 [gray!50, only marks, mark=dot, mark layer=like plot, 
            on layer=axis background,samples=200, domain=0.1:2.9] (x,
            {1.5*(x-0.5)+3+invgauss(rnd,rnd)*x}, 0);
        \addplot3 [Forward] (x, {1.5*(x-0.5)+3}, 0);
        %Forward flat, le spot
        \addplot3 [Forward,black] (x, {forward(0)}, 0);
        %
        %Distributions centrées sur 100
        \addplot3 [distrib,domain=0:10,fill=orange,fill opacity=0.4,draw=none] 
            (0, x, {normal(x, forward(0), 0.5)}) -- 
            (0, 10, 0) -- (0, 0, 0) ;
        \addplot3 [distrib,domain=0:10,orange] (0, x, {normal(x, forward(0), 0.5)});
        \addplot3 [only marks,mark=ball,mark size=2,mark size=2,mark
          options={color=red,line width=0pt}] coordinates {(0, {forward(0)}, 0)}; 
        %Distributions centrées sur le forward
        \pgfplotsinvokeforeach{1,2,3}{
          \addplot3 [distrib,domain=10:{forward(-0.5+#1)-0.01}] 
              (-0.5+#1, x, {normal(x,   {forward(-0.5+#1)}, 0.5+0.25*#1)}) ;
          \addplot3 [fill=red,fill opacity=0.3,domain=0:{forward(-0.5+#1)}] 
              (-0.5+#1, x, {normal(x, {forward(-0.5+#1)},  0.5+0.25*#1)})
              -- (-0.5+#1, {forward(-0.5+#1)},0)  -- (-0.5+#1, 0,0); 
          \addplot3 [distribLeft,domain=0:{forward(-0.5+#1)}] 
              (-0.5+#1, x, {normal(x, {forward(-0.5+#1)},  0.5+0.25*#1)}); 
          \draw[gray] (-0.5+#1, {forward(0)}, 0) -- (-0.5+#1,10,0)
              (-0.5+#1,{forward(-0.5+#1)},0) --
              (-0.5+#1,{forward(-0.5+#1)},{normal({forward(-0.5+#1)}, {forward(-0.5+#1)},  0.5+0.25*#1)});  
          \addplot3 [only marks,mark=ball,mark size=2,mark
             options={color=red,line width=0pt}] coordinates
              {(-0.5+#1, {forward(-0.5+#1)}, 0)}; 
        }
%       
        \path (3, {1.5*(3-0.5)+3}, 0) coordinate (F);
        \coordinate[label={[font=\tiny]Spot}] (B2) at (3.1,0.6,0);
    \end{axis}
    \path (F) node[below,font=\tiny] {Forward};
\end{tikzpicture}
\end{document}

enter image description here

| improve this answer | |
  • I updated the code in my initial question. You're right, I wanted to show the shadow distribution. Merci again ! – JeT Mar 15 at 11:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.