Reputation: 1395
I want to plot two lines, which both have a label, several times in a for loop yielding several plots. In some of those I want the legend to hold both line entries, in some only the handle and label of the first line, leaving the entry for the second line blank. In all cases I need the legend frame to have the exact same size, leaving a blank space in cases where I don't want the second entry.
In theory I just need to turn the second handle and label invisible. I found some solutions with Rectangle()
or Circle()
dummy entries set invisible. However, they don't have the same size as the real legend entry resulting in differing legend frame hight depending on whether I use both lines in the legend or just one line and the dummy. Is there a solution for that?
Here is an example which comes close to what it looks like (despite generating values, of course). Say, in every second iteration I need the lower legend entry to disappear without the legend frame changing its size or shape. How can I do that?
import numpy as np
import matplotlib.pyplot as plt
for i in range(10):
x1 = x2 = y1 = y2 = np.random.rand(5)
yerr1 = yerr2 = .1
plt.figure()
plt.errorbar(x1, y1, yerr=yerr1, c='r', ls='-', marker='.', label='set1')
plt.errorbar(x2, y2, yerr=yerr2, c='k', ls='-', marker='.', label='set2')
# Get rid of error bars in legend
ax.gca()
handles, labels = ax.get_legend_handles_labels()
handles = [n[0:1] for n in handles]
plt.legend(handles, labels, bbox_to_anchor=(0.,1.,1.,0.), loc=3, numpoints=2, ncol=1 ,borderaxespad=0., mode='expand', labelspacing=0.5, borderpad=0.2, handletextpad=0.05)
plt.savefig('test_%d' % i)
plt.close()
Upvotes: 0
Views: 2811
Reputation: 238497
Thanks for the example.
What about something like that:
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.lines as mlines
dummy_white_line = mlines.Line2D([], [], color='white')
for i in range(10):
x1 = x2 = y1 = y2 = np.random.rand(5)
yerr1 = yerr2 = .1
plt.figure()
plt.errorbar(x1, y1, yerr=yerr1, c='r', ls='-', marker='.', label='set1')
plt.errorbar(x2, y2, yerr=yerr2, c='k', ls='-', marker='.', label='set2')
# Get rid of error bars in legend
ax = plt.gca()
handles, labels = ax.get_legend_handles_labels()
if i % 2 == 0:
handles[1] = dummy_white_line
labels[1] = ''
plt.legend(handles, labels, bbox_to_anchor=(0.,1.,1.,0.),
loc=3, numpoints=2, ncol=1 ,borderaxespad=0.,
mode='expand', labelspacing=0.5, borderpad=0.2, handletextpad=0.05)
plt.savefig('test_%d' % i)
#plt.show()
plt.close()
In here I used dummy_white_line to "erase" the line in label (you have white line on white background) and used empty string for a label.
Normal plot:
Plot without (i.e. empty dummy) second label:
Upvotes: 1