HighwayJohn HighwayJohn - 1 month ago 11
Python Question

Removing duplicate mpatches from a list

I startet to work with buttons in my plots (

from matplotlib.widgets import Button
). By pressing the buttons different plots will show up. For that reason my legends do change. I handle this by putting the mpatches in a list:

red_patch = mpatches.Patch(color='red', label='Numerical average')
handlelist.append(red_patch)
ax.legend(handles=handlelist, numpoints=1)


Now if I press the same button twice, the red_patch will also be displayed twice. Because of that I want to delete duplicates but this won't work. So far I tried:

list(set(handelist))


and also:

if red_patch not in handelist:
handlelist.append(red_patch)


But both won't work and I don't understand why. Hope you have an idea :)

Answer

The problem is that:

red_patch = mpatches.Patch(color='red', label='Numerical average')

creates an instance of red_patch every time. The __eq__ operator seems to be unimplemented for this particular type, so the set only compares references of the object, which are not equal.

I would suggest the following code instead:

# declare as ordered dict (so order of creation matters), not list
import collections
handlelist = collections.OrderedDict()

color = 'red'
label = 'Numerical average'

if (color,label) not in handlelist:
    handlelist[(color,label)] = mpatches.Patch(color=color, label=label)

# pass the values of the dict as list (legend expects a list)
ax.legend(handles=list(handlelist.values()), numpoints=1)

The key of your dictionary is the couple (color,label) and when you call the legend method you only get one red_patch, because if the entry already exists, no extra Patch will be created.

Of course, you have to do the same in other parts of your code where you update handlelist. A shared method would be handy:

def create_patch(color,label):
   if (color,label) not in handlelist:
       handlelist[(color,label)] = mpatches.Patch(color=color, label=label)
Comments