3

When there are lots of lines on a plot, a legend isn't always the best way to label them. I often do something like this to label the lines at the right-hand edge of the plot:

def p():
    fig, ax = plt.subplots()
    x = arange(1, 3, 0.01)
    for i,c in zip(range(4), ('r','g','b','m')):
        ax.plot(x, x**i, c=c, lw=2)
        ax.annotate('$x^%d$' % i, (1.01, x[-1]**i),
                    xycoords=('axes fraction', 'data'), color=c)
    return ax

This is only a simple example with a few lines. It looks like this:

>>> p()

enter image description here

But then if I need to change the limits of the plot, the labels are in the wrong place:

>>> p().set_xlim((1.0, 2.0))

enter image description here

Question: what's the easiest way to label lines directly on a plot (without using a legend) in a way that doesn't get broken by changing the axis limits?

Saullo G. P. Castro
  • 56,802
  • 26
  • 179
  • 234
ricklupton
  • 354
  • 2
  • 7
  • I don't know... but I'm curious as to why you wouldn't just make p() a function of the axis limits and call it each time you needed a new plot? – Pete Dec 06 '12 at 18:07
  • You're probably right that that would be the easiest way. But it's nice if the labels are "attached" to the lines for interactive use. – ricklupton Dec 18 '12 at 12:42

1 Answers1

2

You just need to do this:

xlim = 2.0    
def p():
        fig, ax = plt.subplots()
        x = np.arange(1, 3, 0.01)
        for i,c in zip(range(4), ('r','g','b','m')):
            ax.plot(x, x**i, c=c, lw=2)
            ax.annotate('$x^%d$' % i, (1.01, min(x, key=lambda x:abs(x-xlim))**i),
                        xycoords=('axes fraction', 'data'), color=c)
        return ax

Difference in

min(x, key=lambda x:abs(x-xlim))

This thing find near number in list X to the input number

enter image description here

Elenium
  • 348
  • 3
  • 9