# How to draw Brownian motions in tikz/pgf

Here I want to draw some Brownian motions in tikz, like this: Furthermore, I want to truncate the trajectory of Brownian motion, like this:

I have tried many times with random functions in tikz, but always fail.

BTW, the figures uploaded are screenshots from "Brownian Motion - Draft version of May 25, 2008" written by Peter Mörters and Yuval Peres.

-
 Related: Drawing random paths in TikZ – Richard Terrett Jun 15 '12 at 15:36 Why no accept answers? – leo Jun 21 '12 at 19:38 @leo Sorry, how to accept the answer? – XIAO Lishun Jun 23 '12 at 10:18 See here – leo Jun 23 '12 at 13:33

How about this? It's pseudo random, but you can make it repeatable by setting \pgfmathsetseed{integer}:

\documentclass[parskip]{scrartcl}
\usepackage[margin=15mm]{geometry}
\usepackage{tikz}

\begin{document}

\newcommand{\Emmett}[5]{% points, advance, rand factor, options, end label
\draw[#4] (0,0)
\foreach \x in {1,...,#1}
{   -- ++(#2,rand*#3)
}
node[right] {#5};
}

\begin{tikzpicture}
\draw[help lines] (0,-5) grid (15,5);
\Emmett{750}{0.02}{0.2}{red}{first one}
\Emmett{750}{0.02}{0.2}{green}{second one}
\Emmett{750}{0.02}{0.2}{blue}{third one}
\end{tikzpicture}

%\pgfmathsetseed{1337}

\end{document}


Edit 1: Truncated is also doable:

\documentclass[parskip]{scrartcl}
\usepackage[margin=15mm]{geometry}
\usepackage{tikz}

\begin{document}

\newcommand{\Emmett}[5]{% points, advance, rand factor, options, end label
\draw[#4] (0,0)
\foreach \x in {1,...,#1}
{   -- ++(#2,rand*#3)
}
node[right] {#5};
}

\newcommand{\Lathrop}[6]{% points, advance, rand factor, options, end label, truncate from point
\draw[#4] (0,0)
\foreach \x in {1,...,#6}
{   -- ++(#2,rand*#3)
}
coordinate (tempcoord) {};
\pgfmathsetmacro{\remaininglength}{(#1-#6)*#2}
\draw[#4] (tempcoord) -- ++ (\remaininglength,0) node[right] {#5};
}

\begin{tikzpicture}
\draw[help lines] (0,-5) grid (15,5);
\Lathrop{750}{0.02}{0.23}{red!70!black}{first one}{300}
\Lathrop{750}{0.02}{0.18}{green!70!black,thick}{second one}{400}
\Lathrop{750}{0.02}{0.21}{blue!70!black}{third one}{500}
\end{tikzpicture}

\end{document}


Edit 2: Ah, now I get the truncation request: Now you can specify upper and lower bounds and draw straight lines for them:

\documentclass[parskip]{scrartcl}
\usepackage[margin=15mm]{geometry}
\usepackage{tikz}
\usepackage{xifthen}

\begin{document}

\newcommand{\Emmett}[5]{% points, advance, rand factor, options, end label
\draw[#4] (0,0)
\foreach \x in {1,...,#1}
{   -- ++(#2,rand*#3)
}
node[right] {#5};
}

\newcommand{\Lathrop}[9]{% points, advance, rand factor, options, end label, upper, lower trunc, draw trunc  lines, trunc draw options
\begin{scope}
\pgfmathsetmacro{\picwidth}{#1*#2}
\clip (0,#6*28.453+0.5\pgflinewidth) rectangle (\picwidth,#7*28.453-0.5\pgflinewidth);
\ifthenelse{\equal{#8}{y}}
{\draw[#9] (0,#6) -- (\picwidth,#6) (0,#7) -- (\picwidth,#7);}
{}
\draw[#4] (0,0)
\foreach \x in {1,...,#1}
{   -- ++(#2,rand*#3)
}
coordinate (#5) ;
\end{scope}
\node[right,#4] at (#5) {#5};
}

\begin{tikzpicture}
\draw[help lines] (0,-5) grid (15,5);
\Lathrop{750}{0.02}{0.2}{red!70!black}{first one}{1.5}{-2.3}{n}{}
\Lathrop{750}{0.02}{0.2}{green!70!black,thick}{second one}{1.1}{-1.7}{y}{green!70!black,densely dashed}
\Lathrop{750}{0.02}{0.3}{blue!70!black}{third one}{2.4}{-2.7}{y}{blue!70!black,thin,densely dotted}
\end{tikzpicture}

\end{document}


P.S. there are still some issues as the placements of the labels. The command now has 9 parameters, one should switch to pgfkeys for a convineant key-value interface.

-
 Wow, very nice work. The truncation should be noted here. Maybe the figure uploaded before is not clear. I will upload another one. I really appreciate your work. – XIAO Lishun Jun 15 '12 at 2:19 Excellent! I think I can use you codes to make an animation when the truncation increases. Thank you very much. – XIAO Lishun Jun 15 '12 at 14:32

Tom's approach is very nice and fast for general brownian motions, but it's hard to limit the y value of the motion to a certain range (you'd probably have to use clipping).

Here's a different approach, using pgfplotstable to create a table of cumulated sums of random steps, and then plotting these series using pgfplots. You can truncate the series by plotting min(<series>,<value>) or max(<series>,<value>).

Note that this approach is significantly slower than Tom's. In your final document, you'd probably want to use TikZ's external library to speed things up.

\documentclass[11pt, a4paper]{article}
\usepackage{pgfplots, pgfplotstable}

\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}

\begin{document}

\begin{figure}
\begin{tikzpicture}
\begin{axis}[
line join=bevel,
no markers,
table/x expr={\coordindex/400},
xmin=0,
enlarge x limits=false
]