10

For a presentation I want to make a figure showing a graph of a signal with noise. I draw the signal as curved path

\begin{tikzpicture}
  \draw [thick,blue] (0,0) .. controls +(50:3) and +(160:2) .. +(3,0);
\end{tikzpicture}

To add noise I tried to use the random steps decorator. Unfortunately, this decorator randomizes the path in x and y direction. Is there a way to prevent this and only have randomization in the y direction?

  • 4
    Welcome to TeX.sx! If you want to post an answer to your own question you should post it as such (and not include it in your question). – N.N. Sep 14 '11 at 17:58
  • 1
    To echo what N.N. said, this looks like a very neat piece of code, but the nature of the site is that it won't get seen as much with the answer in the question as then it looks (from the front page) as if this question has no answer. So please do as N.N. says and repost the code as an answer. – Andrew Stacey Sep 14 '11 at 18:58
  • This site only allows answering your own question after waiting 8 hours if you have less than 100 reputation. I had to do it like that. – Roland W Sep 15 '11 at 9:31
  • 2
    @Roland: (Maybe we should have an FAQ entry on that) For future information, the way to do that then is to say in your question that you know of one way to do this and that you'll post it when you can (mention the 8hrs thing - I didn't know that) and that you're also interested in seeing what ideas others might have. – Andrew Stacey Sep 15 '11 at 9:48
10

Somewhat similar to @Tom's solution, but using the plot path command:

\documentclass{article}
\usepackage{tikz}

\begin{document}

\begin{tikz}
    \draw plot [domain=-2:2,samples=40,smooth] (\x,{-0.5*\x*\x+0.25*rand});
\end{tikz}
\end{document}

This draws the curve -0.5*x²+0.25*rand, where rand is a pseudo-random number between -1 and 1 that is generated independently at each sampling point of the plot. In the above example, there are 40 sampling points. Changing this number, changes the “wigglyness” of the curve. smooth smoothes out the curve. Remove it to get something closer to the random steps decoration.

example

If you want to fix a particular noise for the image, explicitly set the random seed with \pgfmathsetseed{⟨integer⟩}. It defaults to \time*\year and hence can change between compilation runs.

| improve this answer | |
  • 1
    Well, thats like a lot easier than my solution. But now that I see it, I remember the plot command. However, noise is usually not smooth, as it is not really a modulated function, but a random, discontinuous addition – Tom Bombadil Sep 14 '11 at 21:41
  • \pgfmathsetseed also works with my solution below. It helps a lot if you want to use the same noise multiple times. – Roland W Sep 15 '11 at 11:55
  • Caramdir, I was wondering, would it be possible to use this code for a regular path like \draw[apply effect here] (0,0) -- (10,0);? I tried tweaking it, but ... without success. :P – Alenanno Oct 29 '13 at 14:53
  • @Alenanno: No, this specifically plots a function. For a general path you can use Roland's decorator. – Caramdir Oct 29 '13 at 17:04
8

There is no possibility to prevent the random steps decorator from randomizing in both directions. You have to create your own decorator:

\pgfdeclaredecoration{random ysteps}{start}
{
  \state{start}[width=+0pt,next state=step,
     persistent precomputation=\pgfdecoratepathhascornerstrue]{}
  \state{step}[auto end on length=1.5\pgfdecorationsegmentlength,
           auto corner on length=1.5\pgfdecorationsegmentlength,               
           width=+\pgfdecorationsegmentlength]
  {
    \pgftransformresetnontranslations
    \pgfpathlineto{
      \pgfpoint{cos(\pgfdecoratedangle)*\pgfdecorationsegmentlength}
         {rand*\pgfdecorationsegmentamplitude}
    }
  }
  \state{final}
  {}
}

example output

What makes writing this type of decorator difficult is that pgf wants to make life easy for most types of decorators and transforms the coordinate system so it is tangential to the path at the start of the part being decorated. That way, most decorators become trivial. To get vertical noise these transformations have to be reset. The width of each part of the decoration (which determines the origin for the next invocation of the decorator) is measured in terms of path length, so the distance between the points placed has to account for the rotation angle.

| improve this answer | |
7

A working, yet not very elegant solution:

\documentclass[parskip]{scrartcl}
\usepackage{tikz}

\begin{document}

\begin{tikzpicture}
    \gdef\oldy{-5}  
  \foreach \x in {-4.9,-4.8,...,5}
  { \pgfmathsetmacro{\myfunction}{-0.2*\x*\x}
    \pgfmathsetmacro{\mynoise}{0.3*rand}
    \pgfmathsetmacro{\y}{\myfunction+\mynoise}
    \pgfmathsetmacro{\oldx}{\x-0.1}
    \draw (\oldx,\oldy) -- (\x,\y);
    \xdef\oldy{\y}
  }
\end{tikzpicture}

\end{document}

enter image description here

This draws the function -0.2x² in the interval -5 to 5, withh stepping 0.1. The normal value of the function will "randomly" be of by up to +-0.3. The \oldy stores the last function value for the next iteration (as each iterarion is a group and changes are therefore dismissed afterwards). With some effort, this could also be turned into a \newcommand with parameters.


Edit 1: Here you go:

\documentclass[parskip]{scrartcl}
\usepackage{tikz}
\usetikzlibrary{backgrounds}

\begin{document}

\newcommand{\mynoisefunction}[7]{% function, min, max, step, noise, xscale, yscale
    \begin{tikzpicture}[show background rectangle, xscale=#6, yscale=#7]%
        \gdef\x{#2} 
        \pgfmathsetmacro{\temp}{#1}
        \gdef\oldy{\temp}%
        \pgfmathsetmacro{\secondstep}{#2+#4}%
        \pgfmathsetmacro{\thirdstep}{#2+2*#4}%
      \foreach \x in {\secondstep,\thirdstep,...,#3}%
      { \pgfmathsetmacro{\myfunction}{#1}%
        \pgfmathsetmacro{\mynoise}{#5*rand}%
        \pgfmathsetmacro{\y}{\myfunction+\mynoise}%
        \pgfmathsetmacro{\oldx}{\x-0.1}%
        \draw (\oldx,\oldy) -- (\x,\y);%
        \xdef\oldy{\y}%
      }%
    \end{tikzpicture}%
}

\mynoisefunction{1.5*sin(\x*180/pi)}{-8}{8}{0.1}{0.25}{1}{1}

\end{document}

An automated sin(x) example:

enter image description here

| improve this answer | |

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.