7

I am tying to change the location as well as labels of my legend in Seaborn scatterplot. Here is my code:

ax_total_message_ratio=sns.scatterplot(x='total_messages', y='email_messages_ratio',hue='poi',data=df_new)
ax_total_message_ratio.set_title("Email Messages Ratio vs. Total Messages Across Poi",y=1.12,fontsize=20,fontweight='bold')
ax_total_message_ratio.set_ylabel('Email Messages Ratio')
ax_total_message_ratio.set_xlabel('Total Messages')
ax_total_message_ratio.legend.loc("lower right")
put.show()

enter image description here But I am getting following error message; 'function' object has no attribute 'loc'. Can I get some help on how to control legends with Seaborn? Additionally, I also need to replace 0 by No and 1 by Yes in the legend labels. Thanks

5
  • 2
    Have you tried ax_total_message_ratio.legend(loc="lower right")? Commented Feb 14, 2019 at 2:48
  • @WilliamMiller, Thanks for your clarification. it did help me to fix the location problem.But can I get any guidance on how to change the labels. Help is appreciated
    – jay
    Commented Feb 14, 2019 at 3:00
  • I'm curious how the 0 and 1 got into the legend in the first place. Which seaborn version are you using? (I'm asking because I am unable to construct a plot like the one above that has numbers in the legend, yet categorical colors) Commented Feb 14, 2019 at 4:45
  • @ImportanceOfBeingErnest I am using Seaborn heron 0.9.0.Hope it helps
    – jay
    Commented Feb 14, 2019 at 22:47
  • See also Edit legend title and labels of Seaborn scatterplot and countplot
    – JohanC
    Commented Dec 22, 2022 at 10:23

2 Answers 2

9

You can use the convenience method get_legend_handles_labels() to get the handles and the text of the labels:

ax=sns.scatterplot(x='total_messages', y='email_messages_ratio',hue='poi',data=df_new)

handles, labels  =  ax.get_legend_handles_labels()

ax.legend(handles, ['Yes', 'No'], loc='lower right')
7

You can adjust the position using the loc keyword in calling legend(), like

ax_total_message_ratio.legend(loc="lower right")

To include custom labels for your markers you can create a custom legend, i.e.

import matplotlib.pyplot as plt
from matplotlib.lines import Line2D

custom = [Line2D([], [], marker='.', color='b', linestyle='None'),
          Line2D([], [], marker='.', color='r', linestyle='None')]

fig = plt.figure(figsize=(8,5))

plt.legend(custom, ['Yes', 'No'], loc='lower right')
plt.show()

This will give you

Sample plot with custom legend

and should remove the automatically generated legend, leaving only the custom legend.

6
  • Thanks for your help. It solves my problem.on a side note, the title poi is no more visible. But that's minor. I relabeled as poi and non-poi for the reader's clarity. Highly appreciated.
    – jay
    Commented Feb 14, 2019 at 22:46
  • @jayant You can add the title as a keyword argument title="title" in plt.legend() Commented Feb 14, 2019 at 22:48
  • Thats great. I got that done. one note, it seems we can also use axes object also to use the legend properties, i.e. ax_total_message_ratio.legend(custom,['Non-Poi','Poi'],title="POI"), similarly as you advised with plt.legend. It is helpful to know both of these work. just a note. Great thanks to you.
    – jay
    Commented Feb 14, 2019 at 22:55
  • @jayant Yes you can call legend on an axes object (as I said at the beginning) - I used plt.legend() in my example arbitrarily. Commented Feb 14, 2019 at 22:58
  • 1
    @jjrr Not without seeing the entire code I'm afraid - do you have a link to the code (e.g. on GitHub) that you're using? If not would perhaps you should open a new question and include the code Commented Feb 3, 2020 at 0:35

Not the answer you're looking for? Browse other questions tagged or ask your own question.