pythonmatplotlibseabornlegend

Hide legend labels with underscore in matplotlib>3.10


I create a plot with seaborn that has several lines and error bands. In the legend, I only want to show some of the labels and hide others.

Previously, it was possible to call ax.legend(['one', '_', 'two']) to hide specific labels/artists from appearing in the legend. However, in the newest matplotlib version (>3.10) this behaviour has been removed. As I'm using seaborn, I don't have access to the ax.plot calls themself, in which I could set the labels manually.

Is there any other way to selectively show only some legend labels and suppress others?

import numpy as np
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt

df = pd.DataFrame({'timepoint': np.random.randint(0, 10, 1000),
      'class': np.random.choice(['cat', 'dog', 'duck', 'hare'], 1000),
      'probability': np.random.rand(1000)
})
sns.lineplot(df, x='timepoint', y='probability', hue='class')

# previously, providing underscores as names was hiding the label
# this has unfortunately been deprecated
plt.legend(['cat', *['_']*5, 'hare'])

enter image description here


Solution

  • Store the line plot as ax. Filter or select which handles/labels you pass to ax.legend

    import numpy as np
    import pandas as pd
    import seaborn as sns
    import matplotlib.pyplot as plt
    
    df = pd.DataFrame({'timepoint': np.random.randint(0, 10, 1000),
          'class': np.random.choice(['cat', 'dog', 'duck', 'hare'], 1000),
          'probability': np.random.rand(1000)
    })
    ax = sns.lineplot(df, x='timepoint', y='probability', hue='class')
    
    # grab all handles/labels created by seaborn
    handles, labels = ax.get_legend_handles_labels()
    
    # decide which ones to keep
    keep = ["cat", "hare"]
    new_handles = [h for h, l in zip(handles, labels) if l in keep]
    new_labels  = [l for l in labels if l in keep]
    
    ax.legend(new_handles, new_labels)
    plt.show()
    

    Output:

    enter image description here