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:
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.
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.
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 .
Through the legend parameter set to false and by using the legend function and remove function, the seaborn legend can be easily removed.
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()
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:]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With