如何在 kdeplot / displot 中为每个色调组设置不同的线条样式

Tre*_*ney 4 python matplotlib seaborn displot kdeplot

  • 如何才能给每个hue组的 aseaborn.kdeplotseaborn.displotwithkind='kde'赋予不同的值linestyle
    • 轴级别和图形级别选项都接受strfor linestyle/ls,它适用于所有hue组。
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='-.')
Run Code Online (Sandbox Code Playgroud)
  • kdeplot

在此输入图像描述

  • displot

在此输入图像描述

已审阅的问题

Tre*_*ney 7

  • fill=True要更新的对象位于.collections
  • fill=False要更新的对象位于.lines
  • 更新图例相当简单:
    • handles = p.legend_.legendHandles[::-1]提取并反转图例句柄。linestyle它们被反转更新,因为它们的更新顺序与绘图相反
    • 请注意,图形级图使用 提取图例._legend,轴级图使用.legend_
  • 测试于python 3.8.12, matplotlib 3.4.3,seaborn 0.11.2

kdeplot: 轴级

  • .collections通过或.lines从对象中提取和迭代axes并使用.set_linestyle

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)
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

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)
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

displot:图形级别

  • 与轴级图类似,但每个轴必须迭代
  • 图例handles可以在 中更新for line, ls, handle in zip(ax.collections, lss, handles),但这会将更新应用于每个子图。因此,创建一个单独的循环来仅更新图例handles一次。

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)
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

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)
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述