pythonmatplotlibseaborndisplotkdeplot

How to set a different linestyle for each hue group in a kdeplot / displot


import seaborn as sns
import matplotlib.pyplot as plt

# load sample data
iris = sns.load_dataset("iris")

# convert data to long form
im = iris.melt(id_vars='species')

# axes-level plot works with 1 linestyle
fig = plt.figure(figsize=(6, 5))
p1 = sns.kdeplot(data=im, x='value', hue='variable', fill=True, ls='-.')

# figure-level plot works with 1 linestyle
p2 = sns.displot(kind='kde', data=im, x='value', hue='variable', fill=True, ls='-.')

enter image description here

enter image description here

Reviewed Questions


Solution

  • kdeplot: axes-level

    fill=True

    fig = plt.figure(figsize=(6, 5))
    p = sns.kdeplot(data=im, x='value', hue='variable', fill=True)
    
    lss = [':', '--', '-.', '-']
    
    handles = p.legend_.legendHandles[::-1]
    
    for line, ls, handle in zip(p.collections, lss, handles):
        line.set_linestyle(ls)
        handle.set_ls(ls)
    

    enter image description here

    fill=False

    fig = plt.figure(figsize=(6, 5))
    p = sns.kdeplot(data=im, x='value', hue='variable')
    
    lss = [':', '--', '-.', '-']
    
    handles = p.legend_.legendHandles[::-1]
    
    for line, ls, handle in zip(p.lines, lss, handles):
        line.set_linestyle(ls)
        handle.set_ls(ls)
    

    enter image description here

    displot: figure-level

    fill=True

    g = sns.displot(kind='kde', data=im, col='variable', x='value', hue='species', fill=True, common_norm=False, facet_kws={'sharey': False})
    
    axes = g.axes.flat
    
    lss = [':', '--', '-.']
    
    for ax in axes:
        for line, ls in zip(ax.collections, lss):
            line.set_linestyle(ls)
            
    handles = g._legend.legendHandles[::-1]
    for handle, ls in zip(handles, lss):
        handle.set_ls(ls)
    

    enter image description here

    fill=False

    g = sns.displot(kind='kde', data=im, col='variable', x='value', hue='species', common_norm=False, facet_kws={'sharey': False})
    
    axes = g.axes.flat
    
    lss = [':', '--', '-.']
    
    for ax in axes:
        for line, ls in zip(ax.lines, lss):
            line.set_linestyle(ls)
            
    handles = g._legend.legendHandles[::-1]
    for handle, ls in zip(handles, lss):
        handle.set_ls(ls)
    

    enter image description here