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 would like to be able to specify a mathematical function and be able to use that for multiple purposes including:

  1. Computation of values (see bullet points below)
  2. Graphing using pgfplot
  3. Graphing using pgfplots/gnuplot

This could be considered a followup to: Consistently specify function to be graphed with or without gnuplot which addresses points 2 and 3 where it was pointed out that with the definition of a function as

\newcommand*{\FunctionF}{(x)^3}%

one could use it to plot with just PGFplots, or in conjunction with gnuplot:

\addplot {\FunctionF};
\addplot gnuplot {\FunctionF};

But, I desire a way to also be able to use the same definition to do computations such as where

  • I want to define a piecewise function as in Defining a Piecewise Function for PGFplots,

  • be able to use it to compute values of individual points as in this example where I label a specific point given the x value

  • be able to use it as any other built in math function and define a translation as in the green curve below

enter image description here

So to produce the blue line graph, I have used the \pgfmathdeclarefunction definition which solves problems 1 and 2, and the above referenced question uses the \newcommand*{\FunctionF}{(x)^3} definition to solve problems 2 and 3.

Question: Is there someway of solving problems 1, 2 and 3 all with one definition of the function?

\documentclass[border=5pt]{standalone}
\usepackage{pgfplots}

\newcommand*{\XAxisMin}{-1.0}
\newcommand*{\XAxisMax}{3.0}
\newcommand*{\YAxisMin}{-2.0}
\newcommand*{\YAxisMax}{10}

\newcommand*{\DomainMinF}{\XAxisMin}
\newcommand*{\DomainMaxF}{2.2}

\pgfkeys{/pgfplots/Axis Style/.style={
    xmin=\XAxisMin, xmax=\XAxisMax,
    ymin=\YAxisMin, ymax=\YAxisMax, 
    domain=\DomainMinF:\DomainMaxF,
    width=6.5cm
}}

% Gnuplot options here  have no effect if not using GnuPlot
\pgfkeys{/pgfplots/Plot Style/.style={
    translate gnuplot=true,% can use ‘^’ instead of ‘**’
    id=foo,
    mark=none,
    domain=\DomainMinF:\DomainMaxF,
    samples=50,
    ultra thick,
}}

\newcommand*{\AddLabel}[1]{\node [align = center] at (axis cs: 0.25,7.1) {#1};}%
\newcommand*{\LabelPoint}[2]{\addplot [mark=*] coordinates {(#1,#2)} node [right] {\footnotesize$(#1,#2)$};}%
%-----------------------------

% I would like to only have to specify the function here once
\pgfmathdeclarefunction{FunctionF}{1}{\pgfmathparse{(#1)^(3)}}%
\newcommand*{\FunctionFGnuplot}{(x)^3}%

% Define translation of F
\pgfmathdeclarefunction{FunctionG}{1}{\pgfmathparse{FunctionF(#1+1.0)}}%


\newcommand*{\SpecialXValue}{1.1}%

\begin{document}
\begin{tikzpicture}
\begin{axis}[Axis Style]
    \addplot [Plot Style, blue] ({x},{FunctionF(x)});
    \addplot [Plot Style, green]({x},{FunctionG(x)});

    \AddLabel{1. without \\ Gnuplot}
    \node at (axis cs: 1.8,3.0) [blue] {$f(x)$};
    \node at (axis cs: -0.2,3.0) [green] {$f(x+1)$};

    \pgfmathsetmacro{\YatSpecialX}{FunctionF(\SpecialXValue)}
    \LabelPoint{\SpecialXValue}{\YatSpecialX}
\end{axis}
\end{tikzpicture}
%
\begin{tikzpicture}
\begin{axis}[Axis Style]
    \addplot [Plot Style, red] gnuplot {\FunctionFGnuplot};
    \AddLabel{2. with Gnuplot \\
            \footnotesize(but resorted to using \\
            \footnotesize pgfmathdeclarefunction \\
            \footnotesize to compute point)}

    % How do I do something like this with \FunctionFGnuplot
    \pgfmathsetmacro{\YatSpecialX}{FunctionF(\SpecialXValue)}
    \LabelPoint{\SpecialXValue}{\YatSpecialX}
\end{axis}
\end{tikzpicture}
\end{document}
share|improve this question
    
Instead of using \addplot [mark=*] coordinates {(#1,#2)} node ... in your \LabelPoint, I would suggest using \fill (axis cs:#1,#2) circle [radius=2pt] node .... Starting a whole new plot just for drawing one point will introduce unnecessary overhead, plus it can get in the way if you use legends, because the point will get its own entry unless you use forget plot. –  Jake Nov 4 '11 at 1:41
    
Peter, I suppose an approach like \addplot ... node[pos=0.6] {} is not precisely what you have in mind, right? You want to specify the coordinate here, don't you? Because if a relative position is sufficient, I have an almost stable prototype for it, compare other related questions. The approach includes output of the coordinates of the designated point. –  Christian Feuersänger Nov 4 '11 at 8:55
    
@Jake: Good point about using \fill. I created these macros when I was first starting out and need to go an revisit all of them someday. –  Peter Grill Nov 4 '11 at 17:27
    
@ChristianFeuersänger: The relative position labeling will be extremely useful, but in this case I need to compute values. –  Peter Grill Nov 4 '11 at 17:27
    
Don't you hate it when you spend 30 minutes writing up a question only to realise there is another one which gives you exactly what you need? –  Vivi Feb 13 '13 at 4:48

1 Answer 1

up vote 10 down vote accepted

If you define your function using \def\<function macro>(#1){\pgfmathparse{...#1...}, you can use the function in all the applications you mentioned by saying \<function macro>(x) or \<function macro>(x-1), or \<function macro>(2.4). This will work both when using Gnuplot and when using straight PGFplots:

\documentclass[border=5pt]{standalone}
\usepackage{pgfplots}

\def\FunctionF(#1){(#1)^3}%

\newcommand*{\SpecialXValue}{1.5}%

\begin{document}
\begin{tikzpicture}
\begin{axis}[
    domain=-3:3, samples=50,
    enlargelimits=false,
    ymin=-5, ymax=5,
    every axis plot post/.style= ultra thick]
    \addplot [red] gnuplot {\FunctionF(x)};%
    \addplot [blue] gnuplot {\FunctionF(x+1)};%
    \addplot [cyan] {(x<1)*(3-3*x)+!(x<1)*-\FunctionF(x-1.5))};
    \pgfmathsetmacro{\specialY}{\FunctionF(-1.5)}
    \fill (axis cs:-1.5,\specialY) circle [radius=2pt] node [right] {(2,\specialY)};
\end{axis}


\end{tikzpicture}
\end{document}

Old Answer:

You can redefine the x function to return a constant value (in your case \SpecialXValue) before calculating the y value. The easiest way to do that is to issue

\tikzset{declare function={x=\SpecialXValue;}}

just before you calculate the y value.

You can still add new functions after this, the definition of x as a fixed value doesn't persist.

\documentclass[border=5pt]{standalone}
\usepackage{pgfplots}

\newcommand*{\XAxisMin}{-1.0}
\newcommand*{\XAxisMax}{3.0}
\newcommand*{\YAxisMin}{-2.0}
\newcommand*{\YAxisMax}{10}

\newcommand*{\DomainMinF}{\XAxisMin}
\newcommand*{\DomainMaxF}{2.2}

\pgfkeys{/pgfplots/Axis Style/.style={
    xmin=\XAxisMin, xmax=\XAxisMax,
    ymin=\YAxisMin, ymax=\YAxisMax, 
    domain=\DomainMinF:\DomainMaxF,
    width=6.5cm
}}

% Gnuplot options here  have no effect if not using GnuPlot
\pgfkeys{/pgfplots/Plot Style/.style={
    translate gnuplot=true,% can use ‘^’ instead of ‘**’
    id=foo,
    mark=none,%
    domain=\DomainMinF:\DomainMaxF,%
    samples=50,%
    ultra thick,
}}

\newcommand*{\LabelPoint}[2]{\fill (axis cs:#1,#2) circle [radius=3pt] node [right] {\footnotesize$(#1,#2)$};}%


\newcommand*{\FunctionFGnuplot}{(x)^3}%

\newcommand*{\SpecialXValue}{1.1}%

\begin{document}
\begin{tikzpicture}
\begin{axis}[Axis Style]
    \addplot [Plot Style, red] gnuplot {\FunctionFGnuplot};%

    \tikzset{declare function={x=\SpecialXValue;}}
    \pgfmathsetmacro{\YatSpecialX}{\FunctionFGnuplot}%
    \LabelPoint{\SpecialXValue}{\YatSpecialX}
\end{axis}


\end{tikzpicture}
\end{document}
share|improve this answer
    
Jake, instead of using the \SpecialY construct, I find it easier to just include in the node {(2,{\FunctionF(-1.5)})}. As long as you enclose the \FunctionF() in curly brackets it should compile fine. Any other reason why you use the \SpecialY? –  Vivi Feb 13 '13 at 6:43
    
@Vivi: Yup: Copying from the OP =). I agree with you, \FunctionF(-1.5) seems more readable to me as well. –  Jake Feb 13 '13 at 6:56

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.