matplotlib: 2 different legends on same graph
There's a section in the matplotlib documentation on that exact subject.
Here's code for your specific example:
import itertoolsfrom matplotlib import pyplotcolors = ['b', 'r', 'g', 'c']cc = itertools.cycle(colors)plot_lines = []for p in parameters: d1 = algo1(p) d2 = algo2(p) d3 = algo3(p) pyplot.hold(True) c = next(cc) l1, = pyplot.plot(d1, '-', color=c) l2, = pyplot.plot(d2, '--', color=c) l3, = pyplot.plot(d3, '.-', color=c) plot_lines.append([l1, l2, l3])legend1 = pyplot.legend(plot_lines[0], ["algo1", "algo2", "algo3"], loc=1)pyplot.legend([l[0] for l in plot_lines], parameters, loc=4)pyplot.gca().add_artist(legend1)
Here's an example of its output:
Here is also a more "hands-on" way to do it (i.e. interacting explicitely with any figure axes):
import itertoolsfrom matplotlib import pyplotfig, axes = plt.subplot(1,1)colors = ['b', 'r', 'g', 'c']cc = itertools.cycle(colors)plot_lines = []for p in parameters: d1 = algo1(p) d2 = algo2(p) d3 = algo3(p) c = next(cc) axes.plot(d1, '-', color=c) axes.plot(d2, '--', color=c) axes.plot(d3, '.-', color=c)# In total 3x3 lines have been plottedlines = axes.get_lines()legend1 = pyplot.legend([lines[i] for i in [0,1,2]], ["algo1", "algo2", "algo3"], loc=1)legend2 = pyplot.legend([lines[i] for i in [0,3,6]], parameters, loc=4)axes.add_artist(legend1)axes.add_artist(legend2)
I like this way of writing it since it allows potentially to play with different axes in a less obscure way. You can first create your set of legends, and then add them to the axes you want with the method "add_artist". Also, I am starting with matplotlib, and for me at least it is easier to understand scripts when objets are explicited.
NB: Be careful, your legends may be cutoff while displaying/saving. To solve this issue, use the method axes.set_position([left, bottom, width, length]) to shrink the subplot relatively to the figure size and make the legends appear.
What about using a twin ghost axis?
import matplotlib.pyplot as pltimport numpy as npfig, ax = plt.subplots()colors = ['b', 'r', 'g', ]styles = ['-', '--', '-.']for cc, col in enumerate(colors): for ss, sty in enumerate(styles): print(cc, ss) ax.plot([0, 1], [cc, ss], c=colors[cc], ls=styles[ss])for cc, col in enumerate(colors): ax.plot(np.NaN, np.NaN, c=colors[cc], label=col)ax2 = ax.twinx()for ss, sty in enumerate(styles): ax2.plot(np.NaN, np.NaN, ls=styles[ss], label='style ' + str(ss), c='black')ax2.get_yaxis().set_visible(False)ax.legend(loc=1)ax2.legend(loc=3)plt.show()