Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

I want to define a piecewise function q(x), and attempted to adapt the solution to this question on using pgfmathdeclarefunction to create a unit pulse function, and this works fine. However, when I attempt to plot q(x+4)+0.5, the resulting graph is not what I would expect. However, applying the same transformation on the unit pulse function from the above mentioned link works fine.

So, is there a better way to define a piecewise defined function?

The MWE below produces the following result.

enter image description here

Note that the graphs on the left are as one would expect for both p(x) and p(x+4)+0.5. The graphs on the right are correct for q(x), but but incorrect for q(x+4)+0.5.

\documentclass{article}
\usepackage{amsmath}
\usepackage{pgfplots}

\newcommand{\pLabel}{
$p(x)=
\begin{cases}
    1 & 0 < x < 1\\
    0 & \text{otherwise}
\end{cases}$
}
\newcommand{\qLabel}{
$q(x)=
\begin{cases}
    x & 0 < x < 1\\
    0 & \text{otherwise}
\end{cases}$
}

\newcommand{\pShiftedLabel}{$p(x+4)+0.5$}
\newcommand{\qShiftedLabel}{$q(x+4)+0.5$}

\pgfmathdeclarefunction{p}{1}{%
  \pgfmathparse{(and(#1>0, #1<1))}%
}

\pgfmathdeclarefunction{q}{1}{%
  \pgfmathparse{(and(#1>0, #1<1)*x)}%
}

\tikzstyle{MyStyle}=[domain=-5:5, samples=50, ultra thick]
\tikzstyle{pLabelStyle}=[above, yshift=22ex, xshift=-10ex]
\tikzstyle{qLabelStyle}=[below, yshift=-2ex, xshift=-10ex]
\tikzstyle{ShiftedLabelStyle}=[above left, xshift=1ex]


\begin{document}
%------------------ Using \pgfmathdeclarefunction -----------
Plot of $p(x)$ and \pShiftedLabel using PGF Version \pgfversion, followed by a plot of $q(x)$ and \qShiftedLabel

\begin{tikzpicture}
  \begin{axis}
    \addplot[MyStyle, blue]{p(x)} node [pLabelStyle] {\pLabel};
    \addplot[MyStyle, red]{p(x+4)+0.5} node [ShiftedLabelStyle] {\pShiftedLabel};
  \end{axis}
\end{tikzpicture}
%
\begin{tikzpicture}
  \begin{axis}
    \addplot[MyStyle, blue]{q(x)} node [qLabelStyle] {\qLabel};
    \addplot[MyStyle, red]{q(x+4)+0.5} node [ShiftedLabelStyle] {\qShiftedLabel};
  \end{axis}
\end{tikzpicture}

% --------------------- Using "declare function" -------------
Using declare function to define localp(x) and localq(x):

\begin{tikzpicture}
[declare function={localp(\t) =  and(\t > 0, \t < 1);}]
  \begin{axis}
    \addplot[MyStyle, blue]{localp(x)}  node [pLabelStyle] {\pLabel};
    \addplot[MyStyle, red]{localp(x+4)+0.5} node [ShiftedLabelStyle] {\pShiftedLabel};
  \end{axis}
\end{tikzpicture}
%
\begin{tikzpicture}
[declare function={localq(\t) = (and(\t > 0, \t < 1)*x);}]
  \begin{axis}
    \addplot[MyStyle, blue]{localq(x)} node [qLabelStyle] {\qLabel};
    \addplot[MyStyle, red]{localq(x+4)+0.5} node [ShiftedLabelStyle] {\qShiftedLabel};
  \end{axis}
\end{tikzpicture}
\end{document}
share|improve this question
add comment

1 Answer

up vote 11 down vote accepted

Both methods for defining piecewise functions are fine, but you should use

\pgfmathdeclarefunction{q}{1}{%
  \pgfmathparse{(and(#1>0, #1<1)*#1)}%
}

instead of and(#1>0, #1<1)*x), and

[declare function={localq(\t) = (and(\t > 0, \t < 1)*\t);}]

instead of [declare function={localq(\t) = (and(\t > 0, \t < 1)*x);}], because you don't actually want the function value to be x, but rather the value of the argument (x+4 in this case).

\documentclass{article}
\usepackage{amsmath}
\usepackage{pgfplots}

\newcommand{\pLabel}{
$p(x)=
\begin{cases}
    1 & 0 < x < 1\\
    0 & \text{otherwise}
\end{cases}$
}
\newcommand{\qLabel}{
$q(x)=
\begin{cases}
    x & 0 < x < 1\\
    0 & \text{otherwise}
\end{cases}$
}

\newcommand{\pShiftedLabel}{$p(x+4)+0.5$}
\newcommand{\qShiftedLabel}{$q(x+4)+0.5$}

\pgfmathdeclarefunction{p}{1}{%
  \pgfmathparse{(and(#1>0, #1<1))}%
}

\pgfmathdeclarefunction{q}{1}{%
  \pgfmathparse{(and(#1>0, #1<1)*#1)}%
}

\tikzstyle{MyStyle}=[domain=-5:5, samples=100, ultra thick]
\tikzstyle{pLabelStyle}=[above, yshift=22ex, xshift=-10ex]
\tikzstyle{qLabelStyle}=[below, yshift=-2ex, xshift=-10ex]
\tikzstyle{ShiftedLabelStyle}=[above left, xshift=1ex]


\begin{document}
%------------------ Using \pgfmathdeclarefunction -----------
Plot of $p(x)$ and \pShiftedLabel using PGF Version \pgfversion, followed by a plot of $q(x)$ and \qShiftedLabel

\begin{tikzpicture}
  \begin{axis}
    \addplot[MyStyle, blue]{p(x)} node [pLabelStyle] {\pLabel};
    \addplot[MyStyle, red]{p(x+4)+0.5} node [ShiftedLabelStyle] {\pShiftedLabel};
  \end{axis}
\end{tikzpicture}
%
\begin{tikzpicture}
  \begin{axis}
    \addplot[MyStyle, blue]{q(x)} node [qLabelStyle] {\qLabel};
    \addplot[MyStyle, red]{q(x+4)+0.5} node [ShiftedLabelStyle] {\qShiftedLabel};
  \end{axis}
\end{tikzpicture}

% --------------------- Using "declare function" -------------
Using declare function to define localp(x) and localq(x):

\begin{tikzpicture}
[declare function={localp(\t) =  and(\t > 0, \t < 1);}]
  \begin{axis}
    \addplot[MyStyle, blue]{localp(x)}  node [pLabelStyle] {\pLabel};
    \addplot[MyStyle, red]{localp(x+4)+0.5} node [ShiftedLabelStyle] {\pShiftedLabel};
  \end{axis}
\end{tikzpicture}
%
\begin{tikzpicture}
[declare function={localq(\t) = (and(\t > 0, \t < 1)*\t);}]
  \begin{axis}
    \addplot[MyStyle, blue]{localq(x)} node [qLabelStyle] {\qLabel};
    \addplot[MyStyle, red]{localq(x+4)+0.5} node [ShiftedLabelStyle] {\qShiftedLabel};
  \end{axis}
\end{tikzpicture}
\end{document}

piecewise pgfplots functions

share|improve this answer
    
Thanks, not sure if I ever would have realized my mistake. The problem came about as I had defined \newcommand{\PieceA}{x} and was using that in my original code (I eliminated that for the MWE). So I would have to use \pgfmathparse{(and(#1>0, #1<1)*\PieceA)}. Is there a simple way to change definition of \PieceA to get this to work. I tried the ##1 trick that is used when a newcommand is defined within newcommand, but that didn't work. –  Peter Grill May 31 '11 at 8:27
    
@Peter: Not that I know of. I tried \edef\PieceA{\noexpand#1}, but that doesn't work. This should probably go into a new question, I'm sure there are some TeX cracks who know what to do. –  Jake May 31 '11 at 8:37
    
@Peter I admit that I do not see the bigger picture - it appears as if you really need the macro expansion. Does it help if you make \PieceA dependent on the variable, i.e. \newcommands{\PieceA}[1]{#1}? This would allow you to replace \PieceA by some expression like \newcommand{\PieceA}[1]{(#1+4)} AND it would fix your problem because you could write ...#1<1)*\PieceA{#1})}. But its just guessing. –  Christian Feuersänger Aug 1 '11 at 21:22
    
@Christian: Sorry, we should have linked to the follow-up question and answer: How to define a parameterized command to be consumable in \pgfmathdeclarefunction? –  Jake Aug 1 '11 at 23:17
2  
@Jake thanks for the note - I see. By the way: you have collected a huge bulk of experience with pgfplots. Let me know if you have interest in modifying the pgfplots codebase or in to adding new features! –  Christian Feuersänger Aug 2 '11 at 19:48
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.