Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Modify seaborn line relplot legend title

Tags:

python

seaborn

First off, I am a newbie with both Python and seaborn, but after spending some time with this matter I believe my question has not been addressed elsewhere. If so, I sincerely apologize.

I want to use the seaborn relplot() function with kind='line' to plot data from a dataframe as several lines of different colors. The data corresponding to the lines are separated categorically by values in a column (cat, say) and I use hue (in this case, hue='cat'). Here is a simple example:

import pandas as pd
import seaborn as sns
df = pd.DataFrame({'x': [0, 1, 3, 4, 7, 1, 2, 5, 6],
                   'y': [2, 4, 3, 6, 5, 7, 10, 9, 7],
                   'cat': [0, 0, 0, 0, 0, 1, 1, 1, 1]})
g = sns.relplot(x='x', y='y', hue='cat', kind='line', data=df);

It produces the following graph:

Example plot

How do I modify the legend title without changing the name of the column cat? I believe my problem is that the legend title is actually implemented as a legend item, so what I want to do is remove that item and then add a proper legend title (which I can do using g._legend.set_title('New title')), but I do not know how to accomplish this.

This question differs from Remove seaborn lineplot legend title in that relplot() with kind='line' produces a FacetGrid figure and attaches the legend to that one. This means I cannot access the legend content as g.ax.legend().texts but must use g._legend, in which case I am lost.

like image 721
Robert Avatar asked Nov 02 '18 10:11

Robert


People also ask

How do you customize your legend in Seaborn?

To change the position of a legend in a seaborn plot, you can use the plt. legend() command. The default location is “best” – which is where Matplotlib automatically finds a location for the legend based on where it avoids covering any data points.

How do you make a legend outside the plot in Seaborn?

You can use plt. legend() to control legend properties directly through matplotlib , in accordance with Matplotlib Legend Guide. Note that in Seaborn 0.10. 0 tsplot was removed, and you may replicate (with different values for the estimation if you please) the plots with lineplot instead of tsplot .

How do you delete legends in Seaborn?

Through the legend parameter set to false and by using the legend function and remove function, the seaborn legend can be easily removed.


1 Answers

One option would be to set the first legend entry to an empty string using g._legend.texts[0].set_text(""), then use g._legend.set_title('New title')

import seaborn as sns
df = pd.DataFrame({'x': [0, 1, 3, 4, 7, 1, 2, 5, 6],
                   'y': [2, 4, 3, 6, 5, 7, 10, 9, 7],
                   'cat': [0, 0, 0, 0, 0, 1, 1, 1, 1]})
g = sns.relplot(x='x', y='y', hue='cat', kind='line', data=df)

g._legend.texts[0].set_text("")
g._legend.set_title("New title")
g._legend._legend_box.sep = -5  # move title down slightly

plt.show()

enter image description here

You can also change the horizontal alignment using:

g._legend._legend_box.align = "right"  # or left, or center

Another option would be to draw the legend yourself:

g = sns.relplot(x='x', y='y', hue='cat', kind='line', data=df, legend=False)
ax =g.axes[0][0]

for i, line in enumerate(ax.lines):
    line.set_label(i)

leg = ax.legend()
leg.set_title("New title")

An alternative to setting the first legend entry to an empty string is shown below (suggested by ImportanceOfBeingErnest in the comments):

c = g._legend.get_children()[0].get_children()[1].get_children()[0]
c._children = c._children[1:]
like image 111
DavidG Avatar answered Nov 03 '22 09:11

DavidG