a_guest
a_guest

Reputation: 36249

Update existing legend that contains a PolyCollection

Before going to the PolyCollection issue, I'm already curious if there's a concise way for adding a new element to an existing legend in general. For example:

import matplotlib.pyplot as plt

f, ax = plt.subplots()
ax.legend(handles=ax.plot([0, 1], [0, 1], '-', label='foo'))
p, = ax.plot([1, 2], [1, 2], '--o', label='bar')

Now I would like to add p to the existing legend ax.get_legend(). I found I can do (though it's not really updating):

ax.legend(handles=ax.get_legend().legendHandles + [p])

I feel there should exist a cleaner way. Does it?

Example 1

But when the legend contains a PolyCollection the corresponding label gets lost:

ax.legend(handles=[ax.fill_between([0, 1], 0, 1, color='green', label='foo')])
p = ax.fill_between([1, 2], 0, 1, color='orange', label='bar')
ax.legend(handles=ax.get_legend().legendHandles + [p])

Example 2

Now I was looking for a way to retrieve the labels that are stored inside the legend, however no luck, dir(ax.get_legend()) didn't reveal anything helpful. Interestingly the corresponding handle doesn't know its label either (though it does for the first example with plot):

ax.get_legend().legendHandles[0].get_label()  # Empty string.

So I wonder how the legend knows at all which label corresponds to that handle; it must be stored somewhere inside the legend object.

And my central question: How can I update the existing legend with a new item, without loosing any of the previous information?

Upvotes: 0

Views: 575

Answers (1)

ImportanceOfBeingErnest
ImportanceOfBeingErnest

Reputation: 339310

You do not update a legend. Instead you just create it after your plots.

import matplotlib.pyplot as plt

fig, ax = plt.subplots()

p1 = ax.fill_between([0, 1], 0, 1, color='green', label='foo')
p2 = ax.fill_between([1, 2], 0, 1, color='orange', label='bar')

ax.legend()

plt.show()

If it happens that a plot is created later (e.g. via interactive use or an animation) you still just call legend again.

import matplotlib.pyplot as plt

fig, ax = plt.subplots()

p1 = ax.fill_between([0, 1], 0, 1, color='green', label='foo')
ax.legend()

p2 = ax.fill_between([1, 2], 0, 1, color='orange', label='bar')
ax.legend()

plt.show()

Upvotes: 1

Related Questions