将自定义元素添加到 sns.kdeplot 图例

Add custom elements to sns.kdeplot legend

我想向 Seaborn 中生成的现有图例添加一些自定义元素。这是我的尝试,但没有用:

import seaborn as sns
import numpy as np


_, ax = plt.subplots(figsize=(15, 7))

sns.kdeplot(
    x=np.random.normal(0, 20, size=1000),
    ax=ax,
    hue=np.random.choice([0, 1], size=1000, p=[.1, .9]), 
    common_norm=False,
    fill=True,
)

legend_elements = [
            Line2D([0], [0], color="k", label="xxx"),
            Line2D([0], [0], color="k", ls=":", label="yyy"),
        ]

h = ax.get_legend_handles_labels()

ax.legend(handles=h + legend_elements, loc="upper right" )

问题 1:我想做的是从斧头上捕获现有的手柄和标签,附加海关标签,然后将它们放回去,所以我展示了所有东西。但是我对此有错误。

问题 2:我注意到,如果在显示 kdeplot 后我尝试执行 ax.legend(),它会给我警告“没有找到带有标签的句柄以放入图例”,这很奇怪,因为我确实在图中看到了带有标签的句柄。原因是什么?

非常感谢!

首先,快速说明:ax.get_legend_handles_labels() 会 return 句柄和标签,因此您需要同时抓住两者(例如 h, l = ax.get_legend_handles_labels())。

现在,sns.kdeplot 不使用标准的 matplotlib 图例,而是创建自定义图例。对于这样的自定义图例,matplotlib 的 ax.get_legend_handles_labels() 不起作用。

相反,您可以直接从现有图例中获取这些图例元素的句柄:ax.legend_.legendHandles。由于这些手柄没有包含标签,您还需要从 ax.legend_.texts.

中获取这些标签
import matplotlib.pyplot as plt
from matplotlib.lines import Line2D
import seaborn as sns
import pandas as pd
import numpy as np

_, ax = plt.subplots(figsize=(15, 7))

sns.kdeplot(
    x=np.random.normal(1, 20, size=1000).cumsum(),
    ax=ax,
    hue=np.random.choice([0, 1], size=1000, p=[.1, .9]),
    common_norm=False,
    fill=True,
)

extra_legend_elements = [
    Line2D([0], [0], color="k", label="xxx"),
    Line2D([0], [0], color="k", ls=":", label="yyy"),
]

handles = ax.legend_.legendHandles
for h, t in zip(handles, ax.legend_.texts):
    h.set_label(t.get_text())  # assign the legend labels to the handles
ax.legend(handles=handles + extra_legend_elements, loc="upper right")
plt.tight_layout()
plt.show()