4

For any common x>0, y>0 function the standard axis arrow locations in a pgfplot are great

enter image description here

Unfortunately, for more negative functions (domain or range), the arrows are a bit funny (red = what I want).

enter image description here enter image description here enter image description here

It does seem possible to manually set the arrows right as in pgfplots: y axis arrow pointing down

However what would be fantastic is if it were possible to have te plot use the right arrows automaticly!

I'm thinking some sort of logic such as:

  • If x-axis goes >0 use right arrow
  • If x-axis goes <0 use left arrow
  • If y-axis goes >0 use top arrow
  • If y-axis goes <0 use bottom arrow

However I have no clue how this might be done, would anyone be willing to help?

MWE

\documentclass{article}

\usepackage{pgfplots}
\usetikzlibrary{arrows.meta}

\pgfplotsset{
    no marks,axis lines=middle,
    inner axis line style={-{Latex[length=4mm]}}
}

\begin{document}

\begin{center}
    \begin{tikzpicture}
        \begin{axis}[domain=0:1]
            \addplot+{x};
        \end{axis}
    \end{tikzpicture}
\end{center}

\end{document}
  • How about axis lines*=middle, i.e. adding a *? – user194703 Sep 29 '19 at 5:18
  • Doesn't seem to change anything for me – tecosaur Sep 29 '19 at 5:29
  • Really? Try \documentclass{article} \usepackage{pgfplots} \usetikzlibrary{arrows.meta} \pgfplotsset{ no marks,axis lines*=middle, inner axis line style={-{Latex[length=4mm]}} } \begin{document} \begin{center} \begin{tikzpicture} \begin{axis}[domain=0:1] \addplot+{-x}; \end{axis} \end{tikzpicture} \end{center} \end{document} – user194703 Sep 29 '19 at 5:45
  • I see this i.ibb.co/dbpCdZ0/image.png – tecosaur Sep 29 '19 at 5:51
  • Yes. It is not precisely what you suggest but does not have the problems you are mentioning either. – user194703 Sep 29 '19 at 5:52
4

This does what you suggest, I think. The iaxis style looks whether the origin is left/right/above/below of the axis boundaries, and adds the arrows accordingly.

\documentclass{standalone}
\usepackage{pgfplots}
\pgfplotsset{compat=1.16}
\usetikzlibrary{arrows.meta,calc}

\pgfplotsset{no marks,
    iaxis/.style={,axis lines=middle,
    inner axis line style={-},clip mode=individual,execute at end axis={
    \path[tips=proper] let \p1=($(rel axis cs:1,1)-(axis cs:0,0)$),
     \p2=($(axis cs:0,0)-(rel axis cs:0,0)$)
     in %\pgfextra{\typeout{\x1,\x2,\y1,\y2}}
     \ifdim\x1>0pt
      (axis cs:0,0) edge[-{Latex[length=4mm]}] ({rel axis cs:1,0} |- {axis cs:0,0})
     \fi
     \ifdim\x2>0pt
      (axis cs:0,0) edge[-{Latex[length=4mm]}] ({rel axis cs:0,0} |- {axis cs:0,0})
     \fi
     \ifdim\y1>0pt
      (axis cs:0,0) edge[-{Latex[length=4mm]}] ({rel axis cs:0,1} -| {axis cs:0,0})
     \fi
     \ifdim\y2>0pt
      (axis cs:0,0) edge[-{Latex[length=4mm]}] ({rel axis cs:0,0} -| {axis cs:0,0})
     \fi;
    }},
    every axis/.append style=iaxis
}

\begin{document}
\begin{tabular}{cc}
\begin{tikzpicture}
    \begin{axis}[domain=0:1]
        \addplot+{x};
    \end{axis}
\end{tikzpicture} &
\begin{tikzpicture}
    \begin{axis}[domain=0:1]
        \addplot+{-x};
    \end{axis}
\end{tikzpicture}\\
\begin{tikzpicture}
    \begin{axis}[domain=-1:0]
        \addplot+{x};
    \end{axis}
\end{tikzpicture} &
\begin{tikzpicture}
    \begin{axis}[domain=-1:0]
        \addplot+{-x};
    \end{axis}
\end{tikzpicture}\\
\begin{tikzpicture}
    \begin{axis}[domain=-1:1]
        \addplot+{-x};
    \end{axis}
\end{tikzpicture}
\end{tabular}
\end{document}

enter image description here

Or with overshooting arrows (which alter the dimensions of the axis objects).

\documentclass{standalone}
\usepackage{pgfplots}
\pgfplotsset{compat=1.16}
\usetikzlibrary{arrows.meta,calc}

\pgfplotsset{no marks,
    iaxis/.style={axis lines=middle,
    inner axis line style={-},clip mode=individual,execute at end axis={
    \path[tips=proper] let \p1=($(rel axis cs:1,1)-(axis cs:0,0)$),
     \p2=($(axis cs:0,0)-(rel axis cs:0,0)$)
     in %\pgfextra{\typeout{\x1,\x2,\y1,\y2}}
     \ifdim\x1>0pt
      (axis cs:0,0) edge[-{Latex[length=4mm]}] 
      ($({rel axis cs:1,0} |- {axis cs:0,0})+($(4mm,0)-(0,0)$)$)
     \fi
     \ifdim\x2>0pt
      (axis cs:0,0) edge[-{Latex[length=4mm]}] 
      ($({rel axis cs:0,0} |- {axis cs:0,0})+($(-4mm,0)-(0,0)$)$)
     \fi
     \ifdim\y1>0pt
      (axis cs:0,0) edge[-{Latex[length=4mm]}] 
      ($({rel axis cs:0,1} -| {axis cs:0,0})+($(0,4mm)-(0,0)$)$)
     \fi
     \ifdim\y2>0pt
      (axis cs:0,0) edge[-{Latex[length=4mm]}] 
      ($({rel axis cs:0,0} -| {axis cs:0,0})+($(0,-4mm)-(0,0)$)$)
     \fi;
    }},
    every axis/.append style=iaxis
}

\begin{document}
\begin{tabular}{cc}
\begin{tikzpicture}
    \begin{axis}[domain=0:1]
        \addplot+{x};
    \end{axis}
\end{tikzpicture} &
\begin{tikzpicture}
    \begin{axis}[domain=0:1]
        \addplot+{-x};
    \end{axis}
\end{tikzpicture}\\
\begin{tikzpicture}
    \begin{axis}[domain=-1:0]
        \addplot+{x};
    \end{axis}
\end{tikzpicture} &
\begin{tikzpicture}
    \begin{axis}[domain=-1:0]
        \addplot+{-x};
    \end{axis}
\end{tikzpicture}\\
\begin{tikzpicture}
    \begin{axis}[domain=-1:1]
        \addplot+{-x};
    \end{axis}
\end{tikzpicture}
\end{tabular}
\end{document}

enter image description here

  • You're on fire! Thanks for being so handy. This is great, the only case it doesn't work for is ...[domain=-1:1] \addplot+{x}... – tecosaur Sep 29 '19 at 6:25
  • Also one little thing, not sure if I should put this in a separate question (not sure if solution would transfer), but do you know any good way of preventing the arrowheads and tick marks from overlapping? (see i.ibb.co/Cn1Q6BT/image.png) – tecosaur Sep 29 '19 at 6:38
  • @tecosaur As for the first comment, there was a typo that I fixed. As for the second one, I do not know how to fix this in general. – user194703 Sep 29 '19 at 13:57
  • Would it be possible to extend the arrow position by the length of the arrow? That way they should never overlap. – tecosaur Sep 29 '19 at 14:32
  • @tecosaur Yes, but this would also change the dimensions of the axis, wouldn't it? – user194703 Sep 29 '19 at 14:33

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.