# How determine slope of straight line (with auto scale of axis) in PGF plots

I want to allow automatic scaling of the axis (so don't want to set axis equal=true), and be able to place a label on a line at a manually chosen point along the line. Of course if axis equal=true, then I could simply rotate the node 45 degrees and things work fine. Since I am manually specifying the lengths of the x-axis and y-axis, I attempted to use arctan(\YAxisMax/\XAxisMax), but this isn't quite right. What I need is that ratio of the scale factors applied to each axis.

    \documentclass{standalone}
\usepackage{pgfplots}

\begin{document}
\begin{tikzpicture}

\newcommand*{\XAxisMin}{-7.0}
\newcommand*{\XAxisMax}{7.0}
\newcommand*{\YAxisMin}{-2.0}
\newcommand*{\YAxisMax}{2.0}

% Determine angle of rotation
\pgfmathsetmacro{\Angle}{atan(\YAxisMax/\XAxisMax)}%

\begin{axis}[
axis y line=center, %axis equal=true,
axis x line=middle,
axis on top=true,
xmin=\XAxisMin,
xmax=\XAxisMax,
ymin=\YAxisMin,
ymax=\YAxisMax,
]

% This works fine if axis equal=true above is uncommented.
addplot [mark=none] coordinates{(-1,-1)} node [green, above, rotate=45] {$k=0$};%

\addplot [mark=none] coordinates{(1,1)} node [blue, above, rotate=\Angle] {$k=0$};%

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


Here is the output that this produces:

I thought I found the solution here so tried this which also did not work:

\makeatletter
\pgfpointxy{1}{1}%
\pgfmathsetmacro{\Angle}{atan(\pgf@y/\pgf@x)}%
\makeatother

-

Starting from version 1.5.1, you can place nodes on a plot by adding node [pos=<value>] {...} to the \addplot command. If you add the sloped option to the node options, the node will be rotated to match the plot:

\documentclass{article}
\usepackage{pgfplots}

\begin{document}
\begin{tikzpicture}

\begin{axis}[
axis y line=center,
axis x line=middle,
axis on top=true,
xmin=-7,
xmax=7,
ymin=-4,
ymax=4
]

mark=none,
domain=-4:6,
samples=80,
red,
thick
] {(x<-2)*-2 + (!(x<-2) && (x<3))*x + (!(x<3)) * 3}
node [pos=0.0, above, sloped] {$f(x)=-2$}
node [pos=0.6, above, sloped, blue] {$f(x)=x$}
node [pos=0.9, above, sloped, green!70!black] {$f(x)=3$}
;%
\end{axis}
\end{tikzpicture}
\end{document}


With older versions, one possibility was to use a decoration to place the node. The decorations.markings library allows you to place a (correctly rotated) node somewhere along a path. To use the library in \addplot, you have to apply it through an every path/.style, which leads to a problem with the decoration being applied to itself. Thankfully, this has been solved already: Applying a postaction to every path in TikZ.

Also, PGFplots seems to have a problem with using TikZ nodes in the decorations. This can be avoided by using \pgfnode instead, which does exactly the same as \node, but looks a bit unusual.

Here's an example where a plotlabel style is defined (based on Altermundus' idea in How to label a path drawn using tikz with \draw plot?, and adapted to work around the described problems). You specify the label with plotlabel={<rel pos along path>}{<label text>}. To change the color of the label, you can use \color{<color name>}<label text>. The plotlabel option can be used multiple times to add different labels to the same plot.

\documentclass{article}
\usepackage{pgfplots}
\usetikzlibrary{decorations.markings}
\makeatletter
\tikzset{
nomorepostaction/.code={\let\tikz@postactions\pgfutil@empty},
plotlabel/.style 2 args={
every path/.append style={
postaction={
nomorepostaction,
decorate,
decoration={
markings,
mark=at position #1 with {
\pgfnode{rectangle}{south}{#2}{}{}
}
}
}
}
}
}
\makeatother

\begin{document}
\begin{tikzpicture}

\begin{axis}[
axis y line=center,
axis x line=middle,
axis on top=true,
xmin=-7,
xmax=7,
ymin=-4,
ymax=4
]

mark=none,
domain=-4:6,
samples=80,
red,
thick,
plotlabel={0.0}{\color{purple}$f(x)=-2$},
plotlabel={0.6}{\color{blue}$f(x)=x$},
plotlabel={0.9}{\color{green!70!black}$f(x)=3$}
] {(x<-2)*-2 + (!(x<-2) && (x<3))*x + (!(x<3)) * 3};%
\end{axis}
\end{tikzpicture}
\end{document}


Answer to the original question: You can use Martin Scharrer's method for determining the slope of a line in PGFplots, but only after the axis is finished (otherwise the unit vector is not defined yet) -- you can't calculate the slope before starting the axis. So you have to include your \Angle calculation in a \pgfplotsextra command, which will get executed at the end of the plot. The labels then have to be placed using \nodes positioned using (axis cs:x,y), not with \addplot commands:

\documentclass{standalone}
\usepackage{pgfplots}

\begin{document}
\begin{tikzpicture}

\newcommand*{\XAxisMin}{-7.0}
\newcommand*{\XAxisMax}{7.0}
\newcommand*{\YAxisMin}{-2.0}
\newcommand*{\YAxisMax}{2.0}

\begin{axis}[
axis y line=center, %axis equal=true,
axis x line=middle,
axis on top=true,
xmin=\XAxisMin,
xmax=\XAxisMax,
ymin=\YAxisMin,
ymax=\YAxisMax,
]

\makeatletter
\pgfplotsextra{
\pgfpointxy{1}{1}%
\pgfmathsetmacro{\Angle}{atan(\pgf@y/\pgf@x)}%
\node at (axis cs:-1,-1) [green, above, rotate=\Angle] {$k=0$};
}
\makeatother

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

-
I can't easily use the decoration as this path is part of a bigger plot an each portion requires a separate label, but the second method works fine. Is there anyway to use \addplot to place the nodes instead of \node? The \addplot command is part of an internal macro that I use to label things, so that is why I would prefer to use that. – Peter Grill Jul 8 '11 at 2:03
@Peter: I've changed the style definition to .append style, which means you can add multiple labels using the decorations library. I can't see a way of using addplot to add the labels in this case, because there is no way of adding a plot after the axis is finished (and it has to be finished in order to determine the unit vector). I think you'd be better off adjusting your macro to using \node at (axis cs:<x>,<y>) ..., as this is a much more adequate way of adding labels anyway. – Jake Jul 8 '11 at 2:22