Stop matplotlib repeating labels in legend

Anake picture Anake · Nov 27, 2012 · Viewed 39.1k times · Source

Here is a very simplified example:

xvalues = [2,3,4,6]

for x in xvalues:
    plt.axvline(x,color='b',label='xvalues')

plt.legend()

The legend will now show 'xvalues' as a blue line 4 times in the legend. Is there a more elegant way of fixing this than the following?

for i,x in enumerate(xvalues):
    if not i:
        plt.axvline(x,color='b',label='xvalues')
    else:
        plt.axvline(x,color='b')

Answer

ecatmur picture ecatmur · Nov 27, 2012

plt.legend takes as parameters

  1. A list of axis handles which are Artist objects
  2. A list of labels which are strings

These parameters are both optional defaulting to plt.gca().get_legend_handles_labels(). You can remove duplicate labels by putting them in a dictionary before calling legend. This is because dicts can't have duplicate keys.

For example:

For Python versions < 3.7

from collections import OrderedDict
import matplotlib.pyplot as plt

handles, labels = plt.gca().get_legend_handles_labels()
by_label = OrderedDict(zip(labels, handles))
plt.legend(by_label.values(), by_label.keys())

For Python versions > 3.7

As of Python 3.7, dictionaries retain input order by default. Thus, there is no need for OrderedDict form the collections module.

import matplotlib.pyplot as plt

handles, labels = plt.gca().get_legend_handles_labels()
by_label = dict(zip(labels, handles))
plt.legend(by_label.values(), by_label.keys())

Docs for plt.legend