Search code examples
python-3.xmatplotlibline-plot

Legend overwritten by plot - matplotlib


I have a plot that looks as follows: enter image description here

I want to put labels for both the lineplot and the markers in red. However the legend is not appearning because its the plot is taking out its space.

Update

it turns out I cannot put several strings in plt.legend()

I made the figure bigger by using the following:

 fig = plt.gcf()
 fig.set_size_inches(18.5, 10.5)

However now I have only one label in the legend, with the marker appearing on the lineplot while I rather want two: one for the marker alone and another for the line alone:

enter image description here

Updated code:

plt.plot(range(len(y)), y, '-bD',  c='blue', markerfacecolor='red', markeredgecolor='k', markevery=rare_cases, label='%s' % target_var_name)

fig = plt.gcf()
fig.set_size_inches(18.5, 10.5)

# changed this over here
plt.legend()

plt.savefig(output_folder + fig_name)
plt.close()

Solution

  • What you want to do (have two labels for a single object) is not completely impossible but it's MUCH easier to plot separately the line and the rare values, e.g.

    # boilerplate
    import numpy as np
    import matplotlib.pyplot as plt
    
    # synthesize some data 
    N = 501
    t = np.linspace(0, 10, N)
    s = np.sin(np.pi*t)
    rare = np.zeros(N, dtype=bool); rare[:20]=True; np.random.shuffle(rare)
    
    plt.plot(t, s, label='Curve')
    plt.scatter(t[rare], s[rare], label='rare')
    plt.legend()
    
    plt.show()
    

    enter image description here

    Update

    [...] it turns out I cannot put several strings in plt.legend()

    Well, you can, as long as ① the several strings are in an iterable (a tuple or a list) and ② the number of strings (i.e., labels) equals the number of artists (i.e., thingies) in the plot.

    plt.legend(('a', 'b', 'c'))