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

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

1 Answer 1

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

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

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .