13

I have a code for the Brownian motion and it indicates three paths which initially started at point 0. My goal is to increase the initial starting point from 0.0 to e.g. 0.6. This is achieved by integrating +0.6 in the \addplot command. At the end I aim to have one path that remains in the positive domain, although the path is allowed taking negative values, i.e., in total it should not decrease below 0. However, when I try to delete two paths and hence keep only one that starts at 0.6 and then steadily grows, it automatically starts at 0.0 again. Can somebody help me with that problem?

P.S. I would like not to change anything in the preamble, since I need to illustrate 2 figures in one document, and the first figure will have to refer to the preamble as well. The second figure should be the one that consists of one path starting at 0.6. Thank you very much in advance, I appreciate your help!

Here is the code:

\documentclass[12pt, a4paper]{article}
\usepackage{pgfplots, pgfplotstable}
\usepackage[font=small,labelfont=bf,labelsep=colon]{caption}
\pgfmathsetseed{3}
\pgfplotstablenew[
    create on use/brown1/.style={
        create col/expr accum={\pgfmathaccuma + 0.1*rand}{0}
    },
    create on use/brown2/.style={
        create col/expr accum={\pgfmathaccuma + 0.1*rand}{0}
    },
    create on use/brown3/.style={
        create col/expr accum={\pgfmathaccuma + 0.1*rand}{0}
    },
    columns={brown1,brown2,brown3}
]
{700}
\loadedtable
\begin{document}
\begin{figure}[H]
\caption{Brownian motion}
\centering 
\begin{tikzpicture}
\begin{axis}[
legend pos=outer north east,
axis y line=left, 
axis x line=middle,
xlabel= {\scriptsize Time ($t$)},
ylabel = {\scriptsize Value ($W_{t}$)},
ylabel style = {yshift=-12pt},
xticklabels={,,},
yticklabels={,,},
tick style={draw=none},
line join=bevel,
no markers,
table/x expr={\coordindex/100},
xmin=0,
enlarge x limits=false
]
\addplot table [y expr={max(\thisrow{brown1}+0.6,-5.0)}] {\loadedtable};
\addplot table [y expr={min(\thisrow{brown2}+0.6,5.0)}] {\loadedtable};
\addplot table [y expr=\thisrow{brown3}+0.6] {\loadedtable};
\draw (axis cs:5,5) (axis cs:5,-5);
\legend {{\footnotesize 1st path}, {\footnotesize 2nd path}, {\footnotesize n-th path}};
\end{axis}
\end{tikzpicture}
\end{figure}
\end{document}

![output][1]

ADDITION: this is the code that combines both figures:

\documentclass[12pt, a4paper]{article}
\usepackage{pgfplots, pgfplotstable}
\usepackage[font=small,labelfont=bf,labelsep=colon]{caption}
\makeatletter
\pgfplotsset{
    table/.cd,
    brownian motion/.style={
        create on use/brown/.style={
            create col/expr accum={
                (\coordindex>0)*(
                    max(
                        min(
                            rand*0.1+\pgfmathaccuma,
                            \pgfplots@brownian@max
                        ),
                        \pgfplots@brownian@min
                    )
                ) + (\coordindex<1)*\pgfplots@brownian@start
            }{\pgfplots@brownian@start}
        },
        y=brown, x expr={\coordindex},
        brownian motion/.cd,
        #1,
        /.cd
    },
    brownian motion/.cd,
            min/.store in=\pgfplots@brownian@min,
        min=-inf,
            max/.store in=\pgfplots@brownian@max,
            max=inf,
            start/.store in=\pgfplots@brownian@start,
        start=0
}
\makeatother
\pgfmathsetseed{5}
\pgfplotstablenew[
    create on use/brown1/.style={
        create col/expr accum={\pgfmathaccuma + 0.1*rand}{0}
    },
    create on use/brown2/.style={
        create col/expr accum={\pgfmathaccuma + 0.1*rand}{0}
    },
    create on use/brown3/.style={
        create col/expr accum={\pgfmathaccuma + 0.1*rand}{0}
    },
    columns={brown1,brown2,brown3}
]
{700}
\loadedtable
\begin{document}
\begin{figure}[H]
\caption{Brownian motion}
\centering 
\begin{tikzpicture}
\begin{axis}[
legend pos=outer north east,
axis y line=left, 
axis x line=middle,
xlabel= {\scriptsize Time ($t$)},
ylabel = {\scriptsize Value ($W_{t}$)},
ylabel style = {yshift=-12pt},
xticklabels={,,},
yticklabels={,,},
tick style={draw=none},
line join=bevel,
no markers,
table/x expr={\coordindex/100},
xmin=0,
enlarge x limits=false
]
\addplot table [y expr={max(\thisrow{brown1},-5.0)}] {\loadedtable};
\addplot table [y expr={min(\thisrow{brown2},5.0)}] {\loadedtable};
\addplot table [y expr=\thisrow{brown3}] {\loadedtable};
\draw (axis cs:5,5) (axis cs:5,-5);
\legend {{\footnotesize 1st path}, {\footnotesize 2nd path}, {\footnotesize n-th path}};
\end{axis}
\end{tikzpicture}
\end{figure}
here is some text here is some texthere is some texthere is some texthere is some texthere is some texthere is some texthere is some texthere is some texthere is some texthere is some texthere is some texthere is some texthere is some texthere is some texthere is some texthere is some texthere is some texthere is some texthere is some texthere is some texthere is some texthere is some texthere is some texthere is some texthere is some texthere is some texthere is some texthere is some texthere is some texthere is some texthere is some texthere is some texthere is some texthere is some texthere is some 
\begin{figure}[H]
\caption{Brownian motion}
\centering 
\begin{tikzpicture}
\begin{axis}[
legend pos=outer north east,
axis y line=left, 
axis x line=middle,
xlabel= {\scriptsize Time ($t$)},
ylabel = {\scriptsize Value ($W_{t}$)},
ylabel style = {yshift=-12pt},
xticklabels={,,},
yticklabels={,,},
tick style={draw=none},
line join=bevel,
no markers,
table/x expr={\coordindex/100},
xmin=0,
enlarge x limits=false
]
\addplot table [brownian motion={start=0.3, min=0}] {\loadedtable};
\draw (axis cs:5,5) (axis cs:5,-5);
\end{axis}
\end{tikzpicture}
\end{figure}
\end{document} 

The result is not very satisfactory :(

ajafarov
  • 757
  • 3
    I'm not sure if you care about mathematical correctness, but this is not Brownian motion. You're using rand, which, here, I believe returns uniformly-distributed numbers from -1 to 1. To simulate Brownian motion you need to use normally-distributed random numbers. You have some form of random walk. I see that this terminology has been abused in several other related posts, so you can hardly be faulted. – horchler Jul 27 '13 at 18:42
  • @ horchler, yes I know, actually matlab is more suitable for this, but for the sake of visualization it must be sufficient – ajafarov Jul 27 '13 at 18:45
  • @Jake I tried to combine your codes in one, could you please have a look, the second one looks weird again :((((( – ajafarov Jul 27 '13 at 18:47
  • @horchler: I was wondering about the correct terminology for this as well. If the steps were instead normally distributed, could that be called (one-dimensional) Brownian motion? Or is Brownian motion always in two dimensions? – Jake Jul 27 '13 at 18:51
  • @ajafarov: I'm not sure what exactly you're trying to achieve: Should the second plot show the same blue path as in the first plot, only shifted up by 0.6? – Jake Jul 27 '13 at 18:53
  • @Jake I'll send you a picture now – ajafarov Jul 27 '13 at 18:55
  • @Jake I have edited the question again and added the picture of what I want to have – ajafarov Jul 27 '13 at 19:17
  • So you just want the brown path from the first plot, shifted up by 0.6? – Jake Jul 27 '13 at 19:18
  • @Jake: Brownian motion or one-dimensional Brownian Motion are both fine. Historically, the term described a (roughly) two-dimensional phenomenon, but the term is generic. "Brownian motion" is often used to describe a noise process, B(t), as well as the overall stochastic differential equation dX(t) = μ dt + σ dB(t) with drift μ and diffusion σ. I myself refer to the noise part of the SDE as a Wiener process (In Matlab: cumsum(sqrt(dt)*randn(1,length(t)))) and use W(t) in place of B(t) – the nomenclature is interchangeable. – horchler Jul 27 '13 at 19:40
  • @Jake Yes, and make it look exactly how it is in that picture, everything in one document with some text inbetween – ajafarov Jul 27 '13 at 19:41
  • 1
    @horchler: Excellent, thanks for the explanation! I've corrected the terminology in the first example in my answer, and fixed the code in the second example and in How to draw Brownian motions in tikz/pgf to produce proper Brownian motion (within the limits of the Box-Muller transform for generating random normally distributed numbers). – Jake Jul 27 '13 at 20:05
  • @horchler: Just out of curiosity: Did you see from the plots that the steps weren't normally distributed, or only after examining the code? – Jake Jul 27 '13 at 20:08
  • @Jake: I was just curious how this was done in TeX and looked at the code. If you're interested, in terms of simple transforms, the log-polar method will likely be faster than Box–Muller. – horchler Jul 27 '13 at 20:15

1 Answers1

12

The easiest way to do this is to change the plot command from

\addplot table [y expr={max(\thisrow{brown1}+0.6,-5.0)}] {\loadedtable};

(which limits the path to values greater than -5) to

\addplot table [y expr={max(\thisrow{brown1}+0.6,0.0)}] {\loadedtable};

Complete code that generated the above picture:

\documentclass[12pt, a4paper]{article}
\usepackage{pgfplots, pgfplotstable}
\usepackage[font=small,labelfont=bf,labelsep=colon]{caption}


\pgfmathsetseed{5}
\pgfplotstablenew[
    create on use/randwalk1/.style={
        create col/expr accum={\pgfmathaccuma + 0.1*rand}{0}
    },
    create on use/randwalk2/.style={
        create col/expr accum={\pgfmathaccuma + 0.1*rand}{0}
    },
    create on use/randwalk3/.style={
        create col/expr accum={\pgfmathaccuma + 0.1*rand}{0}
    },
    columns={randwalk1,randwalk2,randwalk3}
]
{700}
\loadedtable
\begin{document}
\begin{figure}[H]
\caption{Random walk}
\centering 
\begin{tikzpicture}
\begin{axis}[
legend pos=outer north east,
axis y line=left, 
axis x line=middle,
xlabel= {\scriptsize Time ($t$)},
ylabel = {\scriptsize Value ($W_{t}$)},
ylabel style = {yshift=-12pt},
xticklabels={,,},
yticklabels={,,},
tick style={draw=none},
line join=bevel,
no markers,
table/x expr={\coordindex/100},
xmin=0,
ymin=-0.5, ymax=3,
enlarge x limits=false
]
\addplot table [y expr={max(\thisrow{randwalk1},-5.0)}] {\loadedtable};
\addplot table [y expr={min(\thisrow{randwalk2},5.0)}] {\loadedtable};
\addplot table [y expr=\thisrow{randwalk3}] {\loadedtable};
\draw (axis cs:5,5) (axis cs:5,-5);
\legend {{\footnotesize 1st path}, {\footnotesize 2nd path}, {\footnotesize n-th path}};
\end{axis}
\end{tikzpicture}
\end{figure}
here is some text here is some texthere is some texthere is some texthere is some texthere is some texthere is some texthere is some texthere is some texthere is some texthere is some texthere is some texthere is some texthere is some texthere is some texthere is some texthere is some texthere is some texthere is some texthere is some texthere is some texthere is some texthere is some texthere is some texthere is some texthere is some texthere is some texthere is some texthere is some texthere is some texthere is some texthere is some texthere is some texthere is some texthere is some texthere is some 

\begin{figure}[H]
\caption{Random walk}
\centering 
\begin{tikzpicture}
\begin{axis}[
legend pos=outer north east,
axis y line=left, 
axis x line=middle,
xlabel= {\scriptsize Time ($t$)},
ylabel = {\scriptsize Value ($W_{t}$)},
ylabel style = {yshift=-12pt},
xticklabels={,,},
yticklabels={,,},
tick style={draw=none},
line join=bevel,
no markers,
table/x expr={\coordindex/100},
xmin=0, ymin=-0.5, ymax=3,
enlarge x limits=false
]
\pgfplotsset{cycle list shift=2}
\addplot table [y expr={min(\thisrow{randwalk3}+0.6,5.0)}] {\loadedtable};
\draw (axis cs:5,5) (axis cs:5,-5);
\end{axis}
\end{tikzpicture}
\end{figure}
\end{document} 

Side note: A better way to limit the path to a certain range is to use the code from my answer to How to draw Brownian motions in tikz/pgf, which doesn't just clip the path at 0, but actually prevents the particle from crossing the zero line; and uses normally distributed steps (which is required for the random walk to be Brownian motion). You would call it like this:

\addplot table [brownian motion={start=0.6, min=0}] {\loadedtable};

Jake
  • 232,450
  • How can I visualize the red or the brown path in the second graph, since they end higher than they begin and it just suits better to the stock prices I try to model? – ajafarov Jul 27 '13 at 16:12
  • @ajafarov: Try a different random seed. \pgfmathsetseed{5} instead of \pgfmathsetseed{3} looks good, for example. – Jake Jul 27 '13 at 16:49
  • @ajafarov: I've edited my answer. Like that? – Jake Jul 27 '13 at 19:54
  • it is so complicated for me now, that I have to ask, are the codes still separeated or two in one, because I need them to be two in one since they are in one document, and I have difficulties to combine them properly – ajafarov Jul 27 '13 at 20:37
  • Sorry if I confused you: I've removed the second code block now. You only need the one big code block from my answer to generate the two plots. The preamble is the same as in your original question. – Jake Jul 27 '13 at 20:40
  • is the united code now under "code for the first example" or "the code for the second example"? – ajafarov Jul 27 '13 at 20:42
  • @ajafarov: There is only one code. – Jake Jul 27 '13 at 20:42
  • yes, now it works))) you made me really happy, thank you very much for your help, sorry for so many misunderstandings and bothering you, but you helped me a lot, DANKE!!!! :) – ajafarov Jul 27 '13 at 20:52
  • and changing the color to red or blue, could you please tell me how it works?)) – ajafarov Jul 27 '13 at 21:07
  • @ajafarov: Hehe, no problem, you're very welcome. You can change the color by using \addplot [red] table [y expr={min(\thisrow{randwalk3}+0.6,5.0)}] {\loadedtable}; – Jake Jul 27 '13 at 21:35
  • I'm sorry, could you also tell me how to make the y-axis stop at point (0;0).. it goes a little bit below the x-axis, although there are no negative values at all.. sorry for bothering, thanks a lot! – ajafarov Jul 27 '13 at 22:43
  • @ajafarov: Sure: Set ymin=0 instead of ymin=-0.5. – Jake Jul 27 '13 at 22:45