14

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).

3 Answers3

20

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

enter image description here

Notes:

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] {xx-4x-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}

Peter Grill
  • 223,288
  • 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 06 '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 06 '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 06 '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 06 '14 at 20:16
16

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

with ticks

\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}
John Kormylo
  • 79,712
  • 3
  • 50
  • 120
  • 1
    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 06 '14 at 21:17
  • Actually, I still have a bug. Let me work a bit more. – John Kormylo Apr 06 '14 at 21:18
  • Okay, I fixed it. – John Kormylo Apr 06 '14 at 21:33
  • Yep, seems to work great. – Peter Grill Apr 06 '14 at 21:37
  • @Peter Grill - i just didn't bother with putting it in a loop. All the work is done in \xcoord{node}. – John Kormylo Apr 06 '14 at 21:37
  • Actually, \xcoord{} cannot be inside a loop. – John Kormylo Apr 07 '14 at 03:47
  • Shouldn't it be easy, instead of drawing the red dots, to draw an extra tick and extra tick label? I'm relly having problem with the syntax in the \fill command. But probably I have to think about it more and look in the manuals :) – Quickbeam2k1 Apr 07 '14 at 06:27
  • 1
    @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 07 '14 at 15:43
  • Is there some reason that values given are wrong? Given a=1, b=-4, and c=-7, I would expect 2±√11, approx 2±3.316625 – Thruston Apr 09 '14 at 00:22
  • @Thurston - The values -1.31 and 5.31 are right (i just double checked). But using \pgfplotsconvertunittocoordinate gave values orders of magnitude off. Besides the axis coordinates and screen coordinates, pgfplot also uses coordinates where the lower left corner is (0,0) and the upper right corner is (1,1). Or it could just be a bug. – John Kormylo Apr 09 '14 at 04:31
3

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}

enter image description here