4

I'm looking for an easy way to handle asymptotes well in pgfplots.

I recently saw Asymptotes in a plot which has lead to me being able to create the following

vasym/.style={
    y filter/.expression = {abs(x-#1)<0.01 ? inf:y},
    before end axis/.append code={
        \draw[densely dashed] ({rel axis cs:0,0} -| {axis cs:#1,0}) -- ({rel axis cs:0,1} -| {axis cs:#1,0});
    }
}

Plot of (x+1)/(x-1) using the key vasym=1 in the axis. enter image description here

However there are a few changes I'd like to make, but have no idea how to do. I'm hoping that someone out here might be able to help

Wishlist

  1. I think it makes more sense to use the key in the \addplot+ options
  2. Follow up to (1): it would be nice if the asymptote line grabbed the colour of the corresponding function
  3. It would be nice if the filter actually got rid of the plot for that region
  4. It would be nice if the filter could be based on something like 0.005 * plot range
  5. Ability to use multiple asymptotes (for functions like tan(x))
  6. A similar horizontal asymptote

MWE

\documentclass{article}

\usepackage{pgfplots}

\pgfplotsset{
    no marks,samples=101,axis lines=middle,
    vasym/.style={
        y filter/.expression = {abs(x-#1)<0.01 ? inf:y},
        before end axis/.append code={
            \draw[densely dashed] ({rel axis cs:0,0} -| {axis cs:#1,0}) -- ({rel axis cs:0,1} -| {axis cs:#1,0});
        }
    }
}

\begin{document}

\begin{center}
    \begin{tikzpicture}
        \begin{axis}[
                domain=0:1.5,
                vasym=1
            ]
            \addplot+[red]{(x+1)/(x-1)};
        \end{axis}
    \end{tikzpicture}
\end{center}

\end{document}

Horizontal asymptote explained

For functions with a horizontal asymptote we really just want

  • a horizontal line at a specified y value
  • with the correct colour
  • specified in the \addplot+ options enter image description here
James
  • 4,587
  • 1
  • 12
  • 27
tecosaur
  • 1,033

1 Answers1

3

How about this?

  1. Can be achieved by replacing before end axis/.append code by xecute at end plot visualization.
  2. Can be achieved by giving the asymptote the current plot style.
  3. Can be achieved by adding unbounded coords=jump.
  4. This value is stored in the pgf key asy interval which you can adjust.
  5. Added a proposal.
  6. Added a proposal.

\documentclass{article}
\usepackage{pgfplots}
\pgfplotsset{compat=1.16}
\pgfplotsset{asy interval/.initial=0.01,
    no marks,samples=101,axis lines=middle,
    vasym/.style={unbounded coords=jump,%<-added
        /utils/exec={\foreach \X [count=\Y] in {#1}
        {\ifnum\Y=1
         \xdef\myfilter{abs(x-\X)<\pgfkeysvalueof{/pgfplots/asy interval}}
        \else
         \xdef\myfilter{\myfilter || abs(x-\X)<\pgfkeysvalueof{/pgfplots/asy interval}} 
        \fi}},
        y filter/.expression = {(\myfilter) ? inf:y},
        execute at end plot visualization={%<-changed
            \begin{scope}
            \clip (rel axis cs:0,0) rectangle (rel axis cs:1,1);
            \foreach \X in {#1}
            {\draw[current plot style,densely dashed%<-added
            ] ({rel axis cs:0,0} -| {axis cs:\X,0}) -- ({rel axis cs:0,1} -|
            {axis cs:\X,0});}
            \end{scope}
        }
    },
    hasym/.style={unbounded coords=jump,%<-added
        execute at end plot visualization={
            \begin{scope}
            \clip (rel axis cs:0,0) rectangle (rel axis cs:1,1);
            \foreach \Y in {#1}
            {\draw[current plot style,densely dashed] ({rel axis cs:0,0} |- {axis
            cs:0,\Y}) -- ({rel axis cs:1,0} |- {axis cs:0,\Y});}
            \end{scope}
        }
    }
}

\begin{document}

\begin{center}
    \begin{tikzpicture}
        \begin{axis}[domain=0:1.5]
            \addplot+[red,vasym={-0.2,0.6,1}]{(x+1)/((x-0.6)*(x-1))};
        \end{axis}
    \end{tikzpicture}
\end{center}
\begin{center}
    \begin{tikzpicture}
        \begin{axis}[ymin=-4,ymax=6,domain=-1.5:1.5]
            \addplot[blue,hasym=1]{1+1/x};
        \end{axis}
    \end{tikzpicture}
\end{center}
\end{document}

enter image description here

  • I'll go through the wishlist:
    1. Nailed it! :D
    2. missing
    3. Got that too!
    4. missing_
    5. Just added this, can you also do this?
    6. Horizontal as for \addplot+[vasym=0]{1/x+5}; there's a horizontal asymp. for y=5
    – tecosaur Sep 29 '19 at 04:24
  • @tecosaur Please see my update. –  Sep 29 '19 at 04:26
  • Great! I've updated the question re: the horizontal asymptope. Other than that and (4) you've got it! I'll probably just wait a bit and see if anybody puts in an answer that gets them all, if nobody does then I'll just mark your's as the answer – tecosaur Sep 29 '19 at 04:40
  • One note on (4), I'm really just looking for something better than abs(x-#1)<0.015 ?, idealy it would be detect when y-value goes outside range, but any improvement is welcome! – tecosaur Sep 29 '19 at 04:41
  • @tecosaur I managed to achieve most things but 5 is more tricky. –  Sep 29 '19 at 04:58
  • Could you do something like have vasyn accept n arguments? – tecosaur Sep 29 '19 at 05:28
  • @tecosaur This does not buy us much here, I am afraid. You need to add the codes for the lines and combine the filters. –  Sep 29 '19 at 05:30
  • Would there be a way to have something like vasym={1,2,3,4} and then use that to construct abs(x-1)<0.01 ? abs(x-2)<0.01 ? abs(x-3)<0.01 ... and execute at end plot visualization/.append? – tecosaur Sep 29 '19 at 05:38
  • @tecosaur Something along those lines works, please see the edit. –  Sep 29 '19 at 05:42
  • That's fantastic! I don't think I could be happier :) Thanks – tecosaur Sep 29 '19 at 05:57
  • Ahhh. One final tweak — would it be possible to do a quick test to only draw asymptotes within the range of the graph? This is because I've changed to clip mode=individual and I'd like to prevent asymptotes from being drawn outside of the graph. – tecosaur Sep 30 '19 at 04:12
  • @tecosaur You only need to add \clip (rel axis cs:0,0) rectangle (rel axis cs:1,1); inside execute at end plot visualization={...}. I added that. –  Sep 30 '19 at 04:18
  • Thanks :) 15charminimum... – tecosaur Sep 30 '19 at 04:22
  • someone suggested an edit to put ´\clip´ in a scope environment. – naphaneal Sep 30 '19 at 10:01
  • @naphaneal that was me. Without that, it had adverse effects on other modifications I'd made to pgfplots. – tecosaur Sep 30 '19 at 12:26
  • @tecosaur OK, I added them. Before I rejected the edit since if one only adds other plots, then obviously nothing goes wrong without the scopes. –  Sep 30 '19 at 14:17
  • This affected me because I was also adding out-of-plot arrows, I don't know how many people who look at this are likely to have something similar going on but I thought better safe than sorry. – tecosaur Sep 30 '19 at 14:53
  • @tecosaur I see. Yes, it does not hurt to add these scopes, I think. –  Sep 30 '19 at 14:56