2

I created a density plot using Seaborn like this:

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

df = pd.DataFrame({'1': np.random.normal(1, 1, 20),
                   '2': np.random.normal(3, 1, 20)})

df = df.melt()
g = sns.displot(df, x='value', hue='variable', kind='kde')

kde.png

Now, I would like to relocate the legend to the upper left. Normally I would do something like this:

plt.legend(loc='lower left', bbox_to_anchor=(0, 1))

However, it cannot find the axis labels and handles. I cannot get them manually either:

handles, labels = g.ax.get_legend_handles_labels()

Is there anyway I can get the handles and labels from the Seaborn FacetGrid to customize the legend?

Alex Waygood
  • 6,304
  • 3
  • 24
  • 46
Wouter
  • 3,201
  • 6
  • 17
  • 6
    New in the latest version: [`seaborn.move_legend()`](http://seaborn.pydata.org/generated/seaborn.move_legend.html#seaborn.move_legend) – mwaskom Aug 19 '21 at 11:00

1 Answers1

2

Exploiting the structure of the dataframe you got from pandas.melt, you can use:

g = sns.displot(df, x='value', hue='variable', kind='kde', legend = False)
plt.legend(df['variable'].unique(), loc='lower left', bbox_to_anchor=(0, 1))

enter image description here

However, pay attention to the fact that this solution work due to df structure and it is not a general solution for every situation.


EDIT

As suggested by mwaskom in the comment to the question, since version 0.11.2, you can use seaborn.move_legend. This approach is general and does not depend on the structure of the dataframe you use to plot.

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

df = pd.DataFrame({'1': np.random.normal(1, 1, 20),
                   '2': np.random.normal(3, 1, 20)})

df = df.melt()
g = sns.displot(df, x='value', hue='variable', kind='kde')

plt.subplots_adjust(top = 0.8)
sns.move_legend(obj = g, loc = 'lower left', bbox_to_anchor = (0.15, 0.82), frameon = True)

plt.show()

enter image description here

Zephyr
  • 11,891
  • 53
  • 45
  • 80