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?

  • 3
    Just remove the axis restrictions and you'll see them :-) pos=0.5 is not always in the visible range. – percusse Sep 18 '12 at 13:57
  • @percusse: You are right, of course. Thanks for pointing that out. – Matthew Leingang Sep 18 '12 at 14:15
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}
| improve this answer | |
  • 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
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

| improve this answer | |
  • Wow, I hadn't thought to try that. Any idea why it doesn't work with 0.5? – Matthew Leingang Sep 18 '12 at 14:11
  • Oh, wait. It might be that pos=0.5 is outside the window... – Matthew Leingang Sep 18 '12 at 14:11
  • @MatthewLeingang yes ;-) – Gonzalo Medina Sep 18 '12 at 14:12
  • Should have thought of that. I need a better way to place the nodes, then. – Matthew Leingang Sep 18 '12 at 14:13
  • @MatthewLeingang You can play around with restrict y to domain=-4:4, to keep the plots stay in the visible range. – percusse Sep 18 '12 at 14:22
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

| improve this answer | |

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.