I would like to be able to specify a mathematical function and be able to use that for multiple purposes including:
- Computation of values (see bullet points below)
- Graphing using pgfplot
- 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
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}
\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 useforget plot
.\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.\fill
. I created these macros when I was first starting out and need to go an revisit all of them someday.