# PGFPlots: How to draw a label at a zero of a function?

Is there an easy method to construct a node (and hence a label) at a zero of a function, i.e. at the intersection of the function with the x-axis? The examples I found were somehow too complicated, and following the KISS principle, I was wondering if there is an elementary method to achieve this.

Edit: To be a bit more precise: I would like to obtain a tick label at the zero of an arbitrary function. The zero should be calculated by the program (so if this is automation, then automation is needed).

• Does need to be automated, or can it be done manually? – cmhughes Apr 6 '14 at 16:47
• I'm a little confused by your comment and edit to your question :) They seem to contradict one another.... – cmhughes Apr 6 '14 at 17:06
• fixed this and deleted the misleading comment. Sorry for the inconvenience – Quickbeam2k1 Apr 6 '14 at 17:20
• possible starting point: pgfplots: Placing node on a specific x-position – cmhughes Apr 6 '14 at 18:13
• You should probably give Peter credit for this one. It's only worth 15 points, but still. – John Kormylo Apr 8 '14 at 3:29

Expanding on @Peter Grill 's solution, here is how to calculate the x coordinates.

\documentclass[border=2pt]{standalone}
\usepackage{pgfplots}
\usetikzlibrary{intersections}

\newlength{\len}
\newlength{\plotwidth}
\newcommand{\getvalue}[1]{\pgfkeysvalueof{/pgfplots/#1}}

%output will be given by \pgfmathresult
\newcommand{\xcoord}[1]% #1 = node name
{\pgfplotsextra{%
\pgfextractx{\len}{\pgfpointdiff{\pgfplotspointaxisxy{0}{0}}{\pgfpointanchor{#1}{center}}}%
\pgfextractx{\plotwidth}{\pgfpointdiff{\pgfplotspointaxisxy{\getvalue{xmin}}{0}}%
{\pgfplotspointaxisxy{\getvalue{xmax}}{0}}}%
\pgfmathparse{\len*(\getvalue{xmax}-\getvalue{xmin})/\plotwidth}%
}}

\begin{document}

\begin{tikzpicture}
\begin{axis}[
axis x line=middle,
axis y line=middle,
domain=-4:7,
xmax=7,
]
\addplot[no marks,blue,thick, name path global=My Graph] {x*x-4*x-7};
\addplot[no marks,draw=none, name path global=x Axis] {0};
\path[name intersections={of=My Graph and x Axis,total=\t}];

\draw[very thin,color=gray] (intersection-1) -- +(0,-5mm) coordinate(tick1);
\xcoord{intersection-1}%
\node[below] at (tick1) {\pgfmathresult};

\draw[very thin,color=gray] (intersection-2) -- +(0,-5mm) coordinate(tick2);
\xcoord{intersection-2}%
\node[below] at (tick2) {\pgfmathresult};
\end{axis}
\end{tikzpicture}
\end{document}

• Excellent!! You might as well provide an answer to Convert from physical dimensions to axis cs coordinate values. Also, I don't think you should assume that there are exactly 2 intersections and there may be 0, 1 or more than 2. – Peter Grill Apr 6 '14 at 21:17
• Actually, I still have a bug. Let me work a bit more. – John Kormylo Apr 6 '14 at 21:18
• Okay, I fixed it. – John Kormylo Apr 6 '14 at 21:33
• Yep, seems to work great. – Peter Grill Apr 6 '14 at 21:37
• @Quickbeam2k1 - The extra ticks have to be given before starting the plot, and they normally look just like ordinary ticks. It is easier to fake them. BTW, \xcoord seem rather fragile: you can't use it inside a node or a path. Also, I tried using \pgfplotsconvertunittocoordinate but it wasn't even close. – John Kormylo Apr 7 '14 at 15:43

Here is an example of how to automatically compute the zero of the function using the intersections library:

## Code

\documentclass[border=2pt]{standalone}
\usepackage{pgfplots}
\usetikzlibrary{intersections}

\begin{document}

\begin{tikzpicture}
\begin{axis}[
axis x line=middle,
axis y line=middle,
domain=-4:7,
xmax=7,
]
\addplot[no marks,blue,thick, name path global=My Graph] {x*x-4*x-7};
\addplot[no marks,draw=none, name path global=x Axis] {0};
\fill[red,name intersections={of=My Graph and x Axis,total=\t}]
\foreach \s in {1,...,\t}{
(intersection-\s) circle (2pt)
};
\end{axis}
\end{tikzpicture}
\end{document}

• Why do you need the x coordinate? You can \draw(intersection-1) +(0,2mm) -- +(-.2mm) for a tick, or (interesection-1 |- y) to locate (x,y). – John Kormylo Apr 6 '14 at 19:20
• @JohnKormylo: Yes, drawing a tick is not a problem, but I thought the OP wanted to label the x value: -1.32 and 5.32 for example. – Peter Grill Apr 6 '14 at 19:23
• Thanks for your answer. In the case I'm considering, the zero of the function is a "critical saturation". Hence, I'd like to have a tick there with an appropriate label. Is it correct, that the coordinate conversion that I'm going to need is explained in the pgfplots manual? – Quickbeam2k1 Apr 6 '14 at 19:51
• @Quickbeam2k1: I haven't looked, but there must be a way to convert the physical coordinate. which is easily extractable via the linked question, into the axis coordinate. If it is helpful I can edit question to show the coordinate in points. – Peter Grill Apr 6 '14 at 20:16

Just for typing exercise with PSTricks.

\documentclass[pstricks,border=12pt,nomessages]{standalone}
\usepackage{pst-eucl,pst-plot,fp}

\psset{yunit=.5}
\def\f(#1){((#1)^2-4*(#1)-7)}
\begin{document}
\begin{pspicture}[algebraic](-3,-12)(7.5,7.5)
\psaxes[Dy=2,Dx=2]{->}(0,0)(-3,-12)(7,7)[$x$,0][$y$,90]
\psplot[linecolor=blue,linewidth=1pt]{-2}{6}{\f(x)}
\FPqsolve{\xa}{\xb}{1}{-4}{-7}
\FPeval\xa{round(xa:2)}\FPeval\xb{round(xb:2)}
\pstInterFF[PointNameSep=17pt,PosAngle=30,PointName=\xa]{\f(x)}{0}{-2}{A}
\pstInterFF[PointNameSep=17pt,PosAngle=150,PointName=\xb]{\f(x)}{0}{5}{B}
\end{pspicture}
\end{document}