62

I would like to remove the title from my seaborn lineplot legend. I tried using this answer to no avail:

import matplotlib.pyplot as plt
import seaborn as sns; sns.set()
fmri = sns.load_dataset("fmri")
fig, ax = plt.subplots()
g = sns.lineplot(x="timepoint", y="signal", hue="event", data=fmri, ax=ax)
ax.legend().set_title('')

Seaborn lineplot still with 'event' title

I get the same if I try to set the title to None. Interestingly, setting the title to something else seems to prepend to the existing title:

ax.legend().set_title('Something else')

Seaborn lineplot still with prepend title

It almost looks like seaborn is treating the title as a hidden legend entry. How can I resolve this?

Daniel
  • 8,179
  • 6
  • 31
  • 56

3 Answers3

106

Important: This answer is about the case when a hue is used that appears as a legend title. In all other cases, the question itself already contains the usual way to get rid of a title.

Indeed, seaborn is misusing a legend label as a (subgroup-)title. Hence the idea can be to either remove this label, or replace it with custom text.

Replacing with custom text:

legend = ax.legend()
legend.texts[0].set_text("Whatever else")

enter image description here

Removing the label:

handles, labels = ax.get_legend_handles_labels()
ax.legend(handles=handles[1:], labels=labels[1:])

enter image description here

After having removed the label you may of course still set another (real) title:

handles, labels = ax.get_legend_handles_labels()
ax.legend(handles=handles[1:], labels=labels[1:], title="Whatever else")

enter image description here

ImportanceOfBeingErnest
  • 321,279
  • 53
  • 665
  • 712
  • In all listed cases, the indexing is no longer needed. `legend.texts[0].set_text("Whatever else")` -> `legend.texts.set_text("Whatever else")` `ax.legend(handles=handles[1:], labels=labels[1:], ...` -> `ax.legend(handles=handles, labels=labels, ...` – Atif Feb 17 '20 at 15:59
  • @AtifRaza That is incorrect. The first suggestion would lead to an error. The second suggestion would not remove the title. – ImportanceOfBeingErnest Feb 17 '20 at 16:08
  • 3
    I needed to change the legend title as well, but your suggestions were removing the legend title as well as the first legend entry. Just checked `ax.legend(handles=handles, labels=labels, title="Split")` again after your comment, and for Seaborn 0.9.0, I am sure indexing from `[1:]` is not correct. Maybe you can check on your side if we have a version mismatch. – Atif Feb 17 '20 at 16:30
  • The [answer](https://stackoverflow.com/a/56925686/2827162) by @badluck is also addressing the same thing. – Atif Feb 17 '20 at 16:32
  • @AtifRaza This answer is tested with seaborn 0.8, 0.9 and 0.10. It works correctly with each of those. – ImportanceOfBeingErnest Feb 17 '20 at 16:40
  • It even says `lineplot` in the question title! (The solution for other plots is already within the question.) – ImportanceOfBeingErnest Feb 17 '20 at 17:07
43
import seaborn as sns
g = sns.lineplot(x="myXs", y="myYs", hue="myHue", data=mydf)
g.legend_.set_title(None)
ofornes
  • 875
  • 1
  • 8
  • 12
  • 16
    Instead of directly accessing the legend instance via `legend_`, you could also use the appropriate getter functions: `g.get_legend().set_title(None)` or `g.legend().set_title(None)` – tschmelz Nov 06 '20 at 08:31
  • One may usually prefer `get_legend()` as it " gives you a reference to the existing legend object" while `legend()` "removes the existing legend and creates a new one". From [this Github issue](https://github.com/mwaskom/seaborn/issues/2669#issuecomment-926611055). – Shengwei Jul 22 '23 at 02:23
9

Extending ImportanceOfBeingErnest's answer:

I had the same problem, but the 'Removing the label' example removed the title and first item from the actual legend.

handles, labels = ax.get_legend_handles_labels()
ax.legend(handles=handles[1:], labels=labels[1:])

So, this removes just the legend title:

handles, labels = ax.get_legend_handles_labels()
ax.legend(handles=handles, labels=labels)
Remolten
  • 2,614
  • 2
  • 25
  • 29
badluck
  • 183
  • 1
  • 11
  • 3
    You don't need the slice index (`[0:]`) as it has no effect. I think your solution simply recreates the legend _without specifying the title_. That assumes you had a legend title in the first place, which `seaborn` doesn't use. Did you need this solution to fix a `seaborn` plot specifically? – Gabriel Oct 14 '19 at 11:02