5

I am studying random walk and I would like to create the image of one in 1-dimension. Here is a pretty good one for 2-dimensional walks: Drawing random paths in TikZ (although for some reason it doesn't recalculate each time - which doesn't really matter). But I can't figure out how to create one for 1 dimension.

I'd like it to look something like this:

enter image description here

What I've tried so far:

\pgfmathsetseed{1}

\begin{tikzpicture}[x=6pt,y=6pt,baseline,scale=1,rotate=45]
 \coordinate (current point) at (0,0);
 \coordinate (old velocity) at (0,0);
 \coordinate (new velocity) at (0.5,rand);
 \foreach \i in {0,1,...,20}
 {
   \draw (current point) 
   .. controls ++([scale=0.2]old velocity) and ++(new velocity) .. ++(0.5,rand)
      coordinate (current point);
   \coordinate (old velocity) at (new velocity);
   \coordinate (new velocity) at (0.5,rand);
 }
\end{tikzpicture}
  • “it doesn't recalculate each time - which doesn't really matter“ → If you have the choice, I think you should favor an approach where the random stuff is not recalculated each time. I noticed that compilation can get noticeably longer when I use, for example, too many tikz decorations that use random numbers. Actually, maybe generating coordinates with a shell script or whatever and drawing a nice plot with gnuplot (or whatever, again) and then including the resulting image in the TeX file would be better. But also slightly less entertaining xD Good luck anyway. – Alice M. Aug 4 '17 at 17:18
  • 2
    You have \pgfmathsetseed that fixes the random output that you will see. Remove that line and you'll get a different output each time. – Aditya Aug 5 '17 at 6:07
  • Ah, thank you @Aditya. I didn't know that. – GerrySmith Aug 5 '17 at 14:03
6

Something like this perhaps?

\documentclass[tikz,margin=5]{standalone}
\begin{document}
\tikz[x=1pt,y=10pt]
  \foreach \c in {red, green, blue}
    \draw [\c] (0,0) \foreach ~ in {0,...,1000}{-- ++(1,{random(0,1)*2-1})};
\end{document}

enter image description here

  • Nice! I think it looks cuter with something like rounded corners = 5pt (unsure about the optimal length) in the options of the tikz command, though ♥. And as I feared, it's slightly long to compile. Nothing prohibitive as long as there is only one or two such figures, I guess. – Alice M. Aug 4 '17 at 19:08
  • @AliceM. there is always \tikzexternalize. – Mark Wibrow Aug 5 '17 at 6:52
  • This looks very good, thanks. Is there a way to add axes to it so that it automatically choosing the limits of the y-axis based on where the line goes? – GerrySmith Aug 5 '17 at 16:21
2

Since you are slightly concerned about speed, here is the Mark Wilbrow's solution ported to Metapost + LuaTeX (I use ConTeXt, but you could use something similar with LuaLaTeX + mplib as well).

\setupMPpage[instance=doublefun]
\starttext
\dorecurse{3}{
\startMPpage
  ux := 0.5pt; 
  uy := 2pt;
  vardef jump = 2*(uniformdeviate 1) - 1 enddef;
  path p;
  z[0] = origin;
  p := z[0] for i = 1 upto 1000 :
    hide(z[i] = z[i-1] + (ux, jump*uy);) -- z[i]
  endfor;

  draw p ;
\stopMPpage}
\stoptext

The instance=doublefun line tells metapost to use double precision (instead of the usual scaled precision. I draw the line three times to get a fair speed comparison with TikZ.

enter image description here

On my 2013 Macbook, I get the following times:

  • For the Mark Wibrow's Tikz solution:

    $time pdflatex --interaction=batchmode rand-ltx.tex 2.45s user 0.02s system 99% cpu 2.491 total

  • For the above luatex + metapost (ConTeXT) solution:

    $time contextjit rand-c --once --noconsole 0.77s user 0.08s system 97% cpu 0.867 total

So metapost is about 3 times faster (Perhaps more, because the load time of luatex + opentype fonts is much larger than the load time of pdftex).

You can also play around with different type of line connections to see which result looks better (I am trying with --, .. tension 2 .. and `.. tension 3 ``.

\setupMPpage[instance=doublefun]
\starttext
\setvalue{line:1}{--}
\setvalue{line:2}{.. tension 2 ..}
\setvalue{line:3}{.. tension 3 ..}
\startTEXpage
\dorecurse{3}
{\startMPcode
  randomseed := 42;
  ux := 1pt; 
  uy := 4pt;
  vardef jump = 2*(uniformdeviate 1) - 1 enddef;
  path p;
  z[0] = origin;
  p := z[0] for i = 1 upto 100 :
    hide(z[i] = z[i-1] + (ux, jump*uy);) \getvalue{line:\recurselevel} z[i]
  endfor;

  draw p ;
\stopMPcode
\endgraf}
\stopTEXpage
\stoptext

which gives

enter image description here

There is a subtle difference between the second and the third curve.

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.