2

Here is a working code (I'll describe it just after) :

    \documentclass[border=2pt]{standalone}
    \usepackage[utf8]{inputenc}

    \usepackage{graphics}
    \usepackage{tikz,pgfplots}
    \usetikzlibrary{math} % Pour evaluate
    \usetikzlibrary{calc} % Pour postionnement relatif

    \newcommand*{\addploZ}[2]{ 
        \addplot[#2,samples=60,domain=0:\Ttrace,thick=3pt,ultra thick,
            evaluate={  \Tun = (1 / ( 6 *(#1-sqrt(#1^2 -1)) ));
                    \Tdeux = (1 / ( 6 *(#1+sqrt(#1^2 -1)) )); }
            ] {  \K * (1 - ( 1/( \Tun - \Tdeux ) )*( \Tun *exp(-x/ \Tun ) - \Tdeux *exp(-x/ \Tdeux ) ))  };
    }

    \newcommand*{\LegendArrows}[5]{ 
        \pgfmathparse{(1 / ( 6 *(#1-sqrt(#1^2 -1)) ))} \pgfmathresult \let\Tun\pgfmathresult
        \pgfmathparse{(1 / ( 6 *(#1+sqrt(#1^2 -1)) ))} \pgfmathresult \let\Tdeux\pgfmathresult
        \coordinate (C2) at (axis cs:#2, {  \K * (1 - ( 1/( \Tun - \Tdeux ) )*( \Tun *exp(-#2/ \Tun ) 
                - \Tdeux *exp(-#2/ \Tdeux ) ))  }) ;
        \draw node[anchor=#3] (#4) at #5 {$z =#2$};
        \draw[fleche] (C2) -- (#4.west) ;
    }       

    \tikzset{ fleche/.style={<-,>=latex,line width=0.2mm,shorten <=-0.02cm} }

    \begin{document}

    \begin{tikzpicture}

    \def\K{2}
    \def\w{(3.14159*2)}
    \def\Ttrace{3}

    \begin{axis}[axis x line=bottom, axis y line = left, width=13cm, height=\axisdefaultheight,ymax=1.55*\K,
    ytick=\empty,extra y ticks={\K}, extra y tick labels={},extra y tick style={grid=major}
    ]

    \addplot[samples=2,domain=0:(\Ttrace+0.1),thick=1pt] { \K };

    \addploZ{2}{blue}
    \addploZ{4}{red}

    \LegendArrows{4}{0.6}{west}{C3}{($(C2)+(axis cs:1,-0.5)$)}
    \LegendArrows{2}{0.6}{south}{C4}{(C3.north)}

    \end{axis}
    \end{tikzpicture}


    \end{document}

It compiles to give you this masterpiece: conjoint arrows on plot But you can see the problem, the arrows point to the same point.

Look at the body, Lets break it down :

\begin{document}
    \begin{tikzpicture}

a few variables for my functions :

    \def\K{2}
    \def\w{(3.14159*2)}
    \def\Ttrace{3}

some plot properties

    \begin{axis}[axis x line=bottom, axis y line = left, width=13cm, height=\axisdefaultheight,ymax=1.55*\K,
    ytick=\empty,extra y ticks={\K}, extra y tick labels={},extra y tick style={grid=major}
    ]

an horizontal asymptot

    \addplot[samples=2,domain=0:(\Ttrace+0.1),thick=1pt] { \K };

Now calling a function created above:

    \addploZ{2}{blue}
    \addploZ{4}{red}

It's calling this one :

\newcommand*{\addploZ}[2]{ 
    \addplot[#2,samples=60,domain=0:\Ttrace,thick=3pt,ultra thick,
        evaluate={  \Tun = (1 / ( 6 *(#1-sqrt(#1^2 -1)) ));
                \Tdeux = (1 / ( 6 *(#1+sqrt(#1^2 -1)) )); }
        ] {  \K * (1 - ( 1/( \Tun - \Tdeux ) )*( \Tun *exp(-x/ \Tun ) - \Tdeux *exp(-x/ \Tdeux ) ))  };
}

You can see I am using evaluate to find the value of two parameters :\Tun et \Tdeux based on the first parameter (I call it z if you want to know) sent to newcommand. So z=2 in the first call and z=4 in the second one.

And since you can see the two curves, evaluate does it work and I get what I want.

The troubles comes after:

Using arrow to point at the curves:

    \LegendArrows{4}{0.6}{west}{C3}{($(C2)+(axis cs:1,-0.5)$)}
    \LegendArrows{2}{0.6}{south}{C4}{(C3.north)}

Calling the function :

\newcommand*{\LegendArrows}[5]{ 
    \pgfmathparse{(1 / ( 6 *(#1-sqrt(#1^2 -1)) ))} \pgfmathresult \let\Tun\pgfmathresult
    \pgfmathparse{(1 / ( 6 *(#1+sqrt(#1^2 -1)) ))} \pgfmathresult \let\Tdeux\pgfmathresult
    \coordinate (C2) at (axis cs:#2, {  \K * (1 - ( 1/( \Tun - \Tdeux ) )*( \Tun *exp(-#2/ \Tun ) 
            - \Tdeux *exp(-#2/ \Tdeux ) ))  }) ;
    \draw node[anchor=#3] (#4) at #5 {$z =#2$};
    \draw[fleche] (C2) -- (#4.west) ;
}       

This gives me colliding arrows because of the evaluation of \Tun and \Tdeux placing the node I called C2. I suppose the two evaluations using \pgfmathparse for the two callings of the function are done before the arrows are plotted, and therefore C2 is placed for both arrows at the same spot (the one of the last evaluation).

You can correct me if I'm wrong.

Anyway I tried other solutions, my first try was to duplicate the code I used to plot the function because I need to evaluate the same quantities, like so:

    \newcommand*{\LegendArrows}[5]{ 
        \coordinate[evaluate={  \Tun = (1 / ( 6 *(#1-sqrt(#1^2 -1)) ));
                    \Tdeux = (1 / ( 6 *(#1+sqrt(#1^2 -1)) )); }
            ] (C2) at (axis cs:#2, {  \K * (1 - ( 1/( \Tun - \Tdeux ) )*( \Tun *exp(-#2/ \Tun ) - \Tdeux *exp(-#2/ \Tdeux ) ))  }) ;
        \draw node[anchor=#3] (#4) at #5 {$z =#2$};
        \draw[fleche] (C2) -- (#4.west) ;
    }

but as I got a compilation error I suppose evaluate is an option of \addplot but not of \coordinate. However it is a option of \node so I can try :

    \newcommand*{\LegendArrows}[5]{ 
        \node[evaluate={  \Tun = (1 / ( 6 *(#1-sqrt(#1^2 -1)) ));
                    \Tdeux = (1 / ( 6 *(#1+sqrt(#1^2 -1)) )); }
            ] (C2) at (axis cs:#2, {  \K * (1 - ( 1/( \Tun - \Tdeux ) )*( \Tun *exp(-#2/ \Tun ) - \Tdeux *exp(-#2/ \Tdeux ) ))  }) {} ;
        \draw node[anchor=#3] (#4) at #5 {$z =#2$};
        \draw[fleche] (C2) -- (#4.west) ;
    }

which gives : separated arrow but gap at the end

You can see here the arrows are separated like I want, but the use of node created that gap between the arrows and the curve which is why I tried to use \coordinate in the first place

And to be thoroughn here comes the end of the body:

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

So to sum up my request, I ask for your help either:

  • to help me with the correct evaluation using \coordinate
  • to correct that gap created whenever I use an empty \node as an anchor.
  • to come up with improvement and clever tricks like this community so often do

Thank you in advance

  • 1
    With nodes: (C2.center) -- (#4.west). – Marijn Jul 22 at 16:26
  • I thought I had tried the center anchor without success, but this time it works fine so thank you. – LMT-PhD Jul 22 at 17:10
  • 1
    \node [coordinate, evaluate=..] or \path[evaluate=...] coordinate...` works. Don't know why it doesn't work with \coordinate directly. – Torbjørn T. Jul 23 at 11:19

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.