This is the solution to defining a piecewise function for pgfplots.

However, I would like to be able to use a macro to define each of the pieces of the function. It is simple to do this if one is using a local declare function as shown in the MWE below which uses \LocalPieceA and \LocalPieceB as the definition of what the function does in the two separate domains.

But, how do I do modify \PieceA and \PieceB so that I can use them in the \pgfmathdeclarefunction? I attempted to use the ## trick that works when defining macros within macros that need to access the parameters of the outer macro, and Jake tried the \edef\PieceA{\noexpand#1} in the above referenced question and that too did not work.


    x & 0 < x < 1\\
   -x+2 & 1 < x < 2\\
    0 & \text{otherwise}

% Want to be able to use \PieceA and \PieceB in the \pgfmathdeclarefunction instead 
% of (#1) and (-#1+2).  With [declare function], this is easy as shown below

  \pgfmathparse{((and(#1>0, #1<1)*#1)+(and(#1>1, #1<4)*(-#1+2)))}%

\tikzstyle{MyPlotStyle}=[domain=-5:5, samples=50, ultra thick]
\tikzstyle{rLabelStyle}=[above, yshift=-15ex, xshift=-25ex]

%------------------ Using \pgfmathdeclarefunction -----------
Plot of $r(x)$ using PGF Version \pgfversion.

    \addplot[MyPlotStyle, red]{q(x)} node [rLabelStyle] {\rLabel};

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

\newcommand{\LocalPieceA}{(\x)}% These two works great!!
[declare function={localr(\x) =  and(\x > 0, \x < 1)*\LocalPieceA+and(\x > 1, \x < 4)*\LocalPieceB;}]
    \addplot[MyPlotStyle, blue]{localr(x)}  node [rLabelStyle] {\rLabel};
  • 1
    When you define a command inside another command, #1 refers to the first parameter of the outer command and ##1 refers to the first parameter of the inner command. #1 is accessible in both the outer and inner commands, but ##1 is only accessible inside the inner command. – xport May 31 '11 at 17:59

Is it what you need?


  \pgfmathparse{((and(#1>0, #1<1)*\PieceA{#1})+(and(#1>1, #1<4)*\PieceB{#1}))}%
| improve this answer | |
  • Yes, this is what I needed. Only excuse I have is that it was late when I had this problem :-) – Peter Grill May 31 '11 at 17:19
  • @Peter: If you don't define a nested command, no reason to use ##1. – xport May 31 '11 at 18:02

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.