Plot functions and their point of intersection

by Mia   Last Updated April 07, 2018 05:23 AM

We are plotting three functions as follows

\documentclass{article}
\usepackage{pgfplots}
\begin{document}
\begin{tikzpicture}
\begin{axis}[enlargelimits=false]

\addplot[domain=0:1,blue] {(1-x)/5};

\addplot[domain=0:1,yellow] {0.5/( 2-x)^3 * 1.0 / sqrt(16 + 14 / (2-x)^4 ) };

\addplot[domain=0:1,red] {
(1/36)*(48*(2-x)^2+16*(2-x)^6-8*(2-x)^3*sqrt(280-792*x+966*x^2-640*x^3+240*x^4-48*x^5+4*x^6))/((2-x)
^2*(4*(2-x)^3+2*sqrt(280-792*x+966*x^2-640*x^3+240*x^4-48*x^5+4*x^6)))};
\end{axis}
\end{tikzpicture}

\end{document}

enter image description here

Please help us in obtaining

  1. Y-axis has a marker 5 * 10 ^{-2}. We only want 0.05

  2. Draw vertical lines from the intersection point between blue and yellow (also between blue and red curve) onto the axis and label the points on the axis.

  3. Instead of lines we want to use symbols for at least two out of three plots.

  4. What else can be done to make it more appealing.



Answers 2


Here is an ugly hack for the answer the unanswered session. I've slightly modified Jake's axis coordinate transformation.

When the marks are introduced, finding intersections would be even more of a hack hence drawing the functions twice might be easier (one for the intersection without drawing, one for the marks). On a personal note, I've tried the only marker curves and intersection in between markers mean nothing visually. Hence you might reconsider that idea. Instead I've color coded the extra nodes to distinguish what is what.

The main difficulty is that the information required is spread out to different layers of TikZ, pgfplots plot, and pgfplots visualization environments. So if anyone else has a better fix I can delete this one.

\documentclass{standalone}
\usepackage{pgfplots}
\pgfplotsset{compat=1.7}
\usetikzlibrary{intersections,plotmarks}

\makeatletter
\def\markxof#1{
\pgf@process{#1}
\pgfmathparse{\pgf@x/\pgfplotsunitxlength +\pgfplots@data@scale@trafo@SHIFT@x)/10^\pgfplots@data@scale@trafo@EXPONENT@x}
}
\makeatother

\begin{document}

\begin{tikzpicture}

\begin{axis}[
enlargelimits=false,
yticklabel style={/pgf/number format/fixed},
domain=0:1,
]

\addplot[name path global=funone,blue] {(1-x)/5};
\addplot[name path global=funtwo,yellow] {0.5/( 2-x)^3 * 1.0 / sqrt(16 + 14 / (2-x)^4 ) };
\addplot[name path global=funthree,red] {
(1/36)*(48*(2-x)^2+16*(2-x)^6-8*(2-x)^3*sqrt(280-792*x+966*x^2-640*x^3+240*x^4-48*x^5+4*x^6))/((2-x)
^2*(4*(2-x)^3+2*sqrt(280-792*x+966*x^2-640*x^3+240*x^4-48*x^5+4*x^6)))};

\path[name intersections={of={funone and funtwo},name=i},
      name intersections={of={funone and funthree},name=in}] (i-1) (in-1);
\pgfplotsextra{
\path (i-1)  \pgfextra{\markxof{i-1}\xdef\myfirsttick{\pgfmathresult}}
      (in-1) \pgfextra{\markxof{in-1}\xdef\mysecondtick{\pgfmathresult}};
}

\end{axis}

\draw[ultra thin, draw=gray] (i-1 |- {rel axis cs:0,0}) node[fill=yellow,yshift=-5ex] 
{\pgfmathprintnumber[fixed,precision=5]\myfirsttick} -- (i-1);
\draw[ultra thin, draw=gray] (in-1 |- {rel axis cs:0,0}) node[fill=red,yshift=-7.5ex] 
{\pgfmathprintnumber[fixed,precision=5]\mysecondtick} -- (in-1);

\end{tikzpicture}

\end{document}

enter image description here

percusse
percusse
February 03, 2013 02:18 AM

The most tricky part of your question is part 2 (in combination with part 3) and the just released PGFPlots v1.16 makes it a bit simpler than before.

Question part 4 is primary opinion based, but I think that yellow isn't a good color on a white background. Also I think it does not really make sense to find intersections between "points" (and "lines") but only between lines. So I personally wouldn't use only marks. (I think you will be able on your own to simplify the code if you follow my suggestion.)

For more details please have a look at the comments in the code.

% used PGFPlots v1.16
\documentclass[border=5pt]{standalone}
\usepackage{pgfplots}
    \usetikzlibrary{
        intersections,
    }
    \pgfplotsset{
        % use this `compat' level or higher to make use of the LUA features
        % (if you compile with LuaLaTeX)
        compat=1.12,
        % for simplicity we declare some functions to avoid repetitions
        /pgf/declare function={
            f(\x) = 0.5/(2-\x)^3 * 1.0 / sqrt(16 + 14/(2-\x)^4);
            g(\x) = (1/36)
                * ( 48 * (2-\x)^2
                    + 16 * (2-\x)^6
                    - 8 * (2-\x)^3 * sqrt(
                        280 - 792*\x + 966*\x^2 - 640*\x^3 + 240*\x^4 - 48*\x^5 + 4*\x^6
                    )
                ) / (
                    (2-\x)^2 * (
                        4*(2-\x)^3
                        + 2*sqrt(
                            280 - 792*\x + 966*\x^2 - 640*\x^3 + 240*\x^4 - 48*\x^5 + 4*\x^6
                        )
                    )
                );
        },
    }
\begin{document}
\begin{tikzpicture}[
    % (see <https://tex.stackexchange.com/a/286127/95441>
    /pgf/number format/NumberStyle/.style={
        fixed,
        precision=3,
    },
]
    \begin{axis}[
        % to question 1.
        yticklabel style={
            /pgf/number format/fixed,
        },
        enlargelimits=false,
%        % uncomment the following option if you want to place the node labels
%        % outside the `axis' environment
%        clip mode=individual,
        % moved common options here
        domain=0:1,
%        % change the number of samples to something that fits your needs
%        samples=25,
        smooth,
    ]

        \addplot [
            blue,
            % name the curves to later be able to find the intersections between them
            name path=one,
            % (because this is a straight line, we only need 2 samples)
            samples=2,
        ]   {(1-x)/5};

        % to question 2
        % intersections can only be found with for lines,
        % but in question 3 you request only marks, this here will only draw
        % an invisible line/path
        \addplot [draw=none,name path=two]      {f(x)};
        \addplot [draw=none,name path=three]    {g(x)};

        % here we draw the two "mark" functions again as such
        \addplot [
            yellow,
            % to question 3.
            only marks,
            mark=*,
        ] {f(x)};
        \addplot [
            red,
            only marks,
            mark=square*,
        ] {g(x)};

        % to question 2.
        \draw [
            red,
            help lines,
            % find the intersection between the lines
            name intersections={
                of=one and two,
                % name the intersection
                by=a,
            },
        ]   (a -| 0,0)
                % -------------------------------------------------------------
                % using `\pgfplotspointgetcoordinates' stores the (axis)
                % coordinates of e.g. the coordinate (a) in `data point',
                % which then can be called by `\pgfkeysvalueof'
                node [below right] {
                    \pgfplotspointgetcoordinates{(a)}
                     $\pgfmathprintnumber[NumberStyle]{\pgfkeysvalueof{/data point/y}}$
                }
                % -------------------------------------------------------------
            -- (a)
            -- (a |- 0,0)
                node [above right,yshift=\pgfkeysvalueof{/pgfplots/major tick length}] {
                    \pgfplotspointgetcoordinates{(a)}
                    $\pgfmathprintnumber[NumberStyle]{\pgfkeysvalueof{/data point/x}}$
                }
        ;

        \draw [
            red,
            help lines,
            name intersections={
                of=one and three,
                by=b,
            },
        ]   (b -| 0,0)
                node [above right] {
                    \pgfplotspointgetcoordinates{(b)}
                     $\pgfmathprintnumber[NumberStyle]{\pgfkeysvalueof{/data point/y}}$
                }
            -- (b)
            -- (b |- 0,0)
                node [above left,yshift=\pgfkeysvalueof{/pgfplots/major tick length}] {
                    \pgfplotspointgetcoordinates{(b)}
                    $\pgfmathprintnumber[NumberStyle]{\pgfkeysvalueof{/data point/x}}$
                }
        ;

    \end{axis}
\end{tikzpicture}
\end{document}

image showing the result of above code

Stefan Pinnow
Stefan Pinnow
April 07, 2018 05:06 AM

Related Questions


How to fill the intersection among four curves?

Updated May 04, 2018 18:23 PM

TikZ: Intersection point with a double-line path

Updated April 10, 2015 19:09 PM


Labeling the intersection of two rays

Updated May 01, 2015 01:10 AM