5

I am plotting a kde plot using the seaborn kdeplot.

time_window_order=['272','268','264','260','256','252','248','244','240']
order_dict = {k:i for i,k in enumerate(time_window_order)}
df =DataFrame ({'time_window':['268','268','268','264','252','252','252','240',
                               '256','256','256','256','252','252','252','240'],
                'seq_no':['a','a','a','a','a','a','a','a',
                          'b','b','b','b','b','b','b','b']})
df['centre_point'] = df['time_window'].map(order_dict)

g =sns.kdeplot(data=df, x="centre_point",hue='seq_no', bw_adjust=0.8);plt.xlim(0,len(time_window_order)-1);plt.grid()
g.legend(loc='center left', bbox_to_anchor=(1, 0.5)) # move legend outside the box
plt.xticks(ticks = range(0,len(time_window_order)) ,labels = time_window_order, rotation = 'vertical')
plt.show()

I tried reposition the legend outside the box using the line g.legend(loc='center left', bbox_to_anchor=(1, 0.5)) [link].

Instead, the compiler return an error

No handles with labels found to put in legend.

Also, instead of complete legend, the legend appear to become like a small rectangle as shown by the red arrow, in the figure below. enter image description here

May I know how to fix this?

mpx
  • 3,081
  • 2
  • 26
  • 56

1 Answers1

1

Seaborn does not handle legends well; you can use this workaround:

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

time_window_order=['272','268','264','260','256','252','248','244','240']
order_dict = {k:i for i,k in enumerate(time_window_order)}
df = pd.DataFrame ({'time_window': ['268','268','268','264','252','252','252','240',
                                    '256','256','256','256','252','252','252','240'],
                    'seq_no': ['a','a','a','a','a','a','a','a',
                               'b','b','b','b','b','b','b','b']})
df['centre_point'] = df['time_window'].map(order_dict)

g = sns.FacetGrid(df, hue="seq_no", height=6, aspect=1.5)
g = (g.map(sns.kdeplot, "centre_point", bw_adjust=0.8))

plt.xlim(0, len(time_window_order)-1)
plt.ylabel('density')
plt.legend(bbox_to_anchor=(1.2, 0.5))
plt.tight_layout()
plt.xticks(ticks=range(0, len(time_window_order)), labels=time_window_order, rotation='vertical')
plt.grid()

plt.show()

Output:

KDE Plot

David M.
  • 4,518
  • 2
  • 20
  • 25
  • Thanks David, but I think this way around might have issue when one would like to append another ax on top of the other. – mpx Feb 23 '21 at 09:55
  • Could you give an example? – David M. Feb 23 '21 at 09:56
  • 1
    Say for example: `ax=sns.kdeplot(data=df0, x="centre_point",hue='feature', bw_adjust=0.5) ax=sns.kdeplot(data=df1, x="centre_point",hue='feature', bw_adjust=0.5,ax=ax)` Usually, one will pass the `ax` onto the second handle to get multiple kde in a single plot. I will make a sample data and perhaps post new OP to better explain about this – mpx Feb 23 '21 at 09:58