5

I would like to plot the family of curves with equation xy=c for several values of c. I also want each curve to be labeled with the value of c it corresponds to.

Here is my MWE:

\documentclass{standalone}
\usepackage{tikz}
\usepackage{pgfplots}

\begin{document}
\begin{tikzpicture}
    \begin{axis}[
        xmin=-3.0,xmax=3.0,
        ymin=-3.0,ymax=3.0,
        axis x line=middle, 
        axis y line=middle,
        axis equal image,
        cycle list={blue}
        ]
        \pgfplotsinvokeforeach{-3.0,-2.5,...,-0.5,0.5,1.0,...,3.0}{
            \addplot+[domain=-3:-0.1,forget plot] {#1/x};
            \addplot+[domain=0.1:3] {#1/x} node[pos=0.5] {$#1$};
        }
    \end{axis}
\end{tikzpicture}
\end{document}

I get each curve plotted, but only two of them are labeled:

sample code output

How do I get all twelve curves labeled?

Matthew Leingang
  • 44,937
  • 14
  • 131
  • 195

3 Answers3

6

If you use a different value for pos, they will be visible:

\documentclass{standalone}
\usepackage{tikz}
\usepackage{pgfplots}

\begin{document}
\begin{tikzpicture}
    \begin{axis}[
        xmin=-3.0,xmax=3.0,
        ymin=-3.0,ymax=3.0,
        axis x line=middle, 
        axis y line=middle,
        axis equal image,
        cycle list={blue}
        ]
        \pgfplotsinvokeforeach{-3.0,-2.5,...,-0.5,0.5,1.0,...,3.0}{
            \addplot+[domain=-3:-0.1,forget plot] {#1/x};
            \addplot+[domain=0.1:3] {#1/x} node[pos=0.92] {$#1$};
        }
    \end{axis}
\end{tikzpicture}
\end{document}

enter image description here

Gonzalo Medina
  • 505,128
3

To get finer control over the placement of the nodes, you could adapt my approach from Label plots in pgfplots without entering coordinates manually. For example, you could define a curved path and place all the labels at the intersections of their plot and the path:

\documentclass[border=5mm]{standalone}
\usepackage{tikz}
\usepackage{pgfplots}
\usetikzlibrary{intersections}

\pgfkeys{
    /pgfplots/linelabel/.style={
        name path global=labelpath,
        execute at end plot={
            \path [name path global = labelpositionline]
                (rel axis cs:0.85,0) to [bend left=45, looseness=1] (rel axis cs:0.85,1);
            \path [name intersections={of=labelpath and labelpositionline}] (intersection-1) node [font=\scriptsize] {#1};
        },
    }
}


\begin{document}
\begin{tikzpicture}
    \begin{axis}[
        xmin=-3.0,xmax=3.0,
        ymin=-3.0,ymax=3.0,
        axis x line=middle, 
        axis y line=middle,
        axis equal image,
        cycle list={blue}
        ]
        \pgfplotsinvokeforeach{-3.0,-2.5,...,-0.5,0.5,1.0,...,3.0}{
            \addplot+[domain=-3:-0.1,forget plot] {#1/x};
            \addplot+[linelabel=#1,domain=0.1:3] {#1/x};
        }
    \end{axis}
\end{tikzpicture}
\end{document}
Jake
  • 232,450
  • Very cool. I was looking for an intersections solution but I was not able to refer to the plot by name. I was using name path instead of name path global and that must be the difference. – Matthew Leingang Sep 19 '12 at 12:14
2

As the first few commenters pointed out, the labels were placed, just outside the window defined by the pgfplots ymin/ymax keys.

My workaround was to alert the domain of each plotted function so that there were no points outside the window. Then pos=0.5 was exactly where I wanted it.

    \pgfplotsinvokeforeach{-3.0,-2.5,...,-0.5,0.5,1.0,...,3.0}{
        \pgfmathsetmacro{\a}{abs(#1)/3}
        \addplot+[domain=-3:-\a,forget plot] {#1/x};
        \addplot+[domain=\a:3] {#1/x} node[black,fill=white,pos=0.5,sloped,inner sep=0pt] {$#1$};
    }

The disadvantage is that if ymin or ymax were changed the line defining \a would need to be updated. So it's not optimal but the output is not bad.

enter image description here

Matthew Leingang
  • 44,937
  • 14
  • 131
  • 195