Sorry, this content is no longer available

Ask Your Question
1

Legend attached to curve in plot ("PlotLabels")

asked 6 years ago

Bacco gravatar image

updated 6 years ago

Hello,

I have a plot with several curves (say, 5) and I need to clearly mark them.

The plot should be grayscale friendly (I am giving curves different shades, but it is not enough), and line style (dotted...) already has a different meaning. I am using a legend, but it goes in a separate box and does not really help a lot.

Since the different curves never cross in a given plot, just attaching the legend label to the curve tail would be great: how can I achieve this? To be clear, I am looking for an equivalent of Mathematica PlotLabels.

The following example gives an idea of the 'most overlapping' case I can be interested in (actually an exaggeration, a real plot would stop at nexp=2.5):

f(x,n) = e^(-1/(n*x))
listexp = srange(0.5, 3+0.1, 0.5)
lenght = float(len(listexp))
xMinPlot = 0.1

p = Graphics()
for i,nexp in enumerate(listexp) :
    c = 10^nexp
    p += plot_semilogx(f(x,c), (x, xMinPlot, 10), hue=i/lenght)

p.show()

Using slelievre answer (and imitating the PlotLabels idea, putting gray lines between plot and label), I came up with this:

text_options = {...}
offsets = [0.01, 0.01, 0.01, -0.02, -0.02, 0.02]
xlabel = xMinPlot*0.85
xline  = xMinPlot*0.97

for i,nexp in enumerate(listexp) :
    c = 10^nexp
    yline = f(xMinPlot,c)
    p += line(((xline,yline),(xlabel,yline+offsets[i])), color='gray', thickness=0.5)
    p += text('$c = 10^{{ {:.1f} }}$'.format(float(nexp)),
        (xlabel, yline+offsets[i]), **text_options)

p.show(xmin=5*10^-2, xmax=10)

This approach requires to analyse each plot case by case and playing around to find a solution, but I am afraid there is nothing one can do to partially automate it. Also, I am not sure that I am doing this the best way, or whether the result could look better/more professional.

Preview: (hide)

Comments

Even without uploading the picture, please provide the code for plotting the curves.

This will help others come up with helpful answers.

slelievre gravatar imageslelievre ( 6 years ago )

Having read the solution ("add labels manually") I now see why a more concrete example than f(x) = n*x is useful. I will add a simplified version of one of my real plots.

Bacco gravatar imageBacco ( 6 years ago )

1 Answer

Sort by » oldest newest most voted
3

answered 6 years ago

slelievre gravatar image

The following might be a step in the right direction.

Define a list of functions to plot:

sage: ff = [
....:     lambda x: 1 + exp(-x^2/8)*sin(x^2)/x^1,
....:     lambda x: 2 + exp(-x^2/8)*sin(x^3)/x^2,
....:     lambda x: 3 + exp(-x^2/8)*sin(x^4)/x^3,
....:     lambda x: 4 + exp(-x^2/8)*sin(x^5)/x^4,
....:     ]

Initialize an empty graphics object:

sage: p = Graphics()

Set some text options:

sage: text_options = {
....:     'horizontal_alignment': 'right',
....:     'vertical_alignment': 'bottom',
....:     'fontsize': 'large'}

Plot each function and add a label at the end of the curve:

sage: for i, f in enumerate(ff):
....:     p += plot(f, (-5, 5), hue=(2*i+1)/10)
....:     p += text('$y = f_{}(x)$'.format(i), (5, f(5)), **text_options)

Show the result:

sage: p.show()

Curves with labels

Preview: (hide)
link

Comments

This is very useful: it's simple and works out of the box in many cases.

Bacco gravatar imageBacco ( 6 years ago )

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer

Question Tools

1 follower

Stats

Asked: 6 years ago

Seen: 1,028 times

Last updated: May 01 '19