如何将标签添加到 seaborn 箱线图集

How to add labels to sets of seaborn boxplot

我有两套箱线图,一套是蓝色的,一套是红色的。我希望图例显示每组箱线图的标签,即

图例: -蓝框- A, -红框- B

sns.boxplot() 中添加了 labels='A'labels='B',但无法使用错误消息 “找不到带有标签的艺术家放入图例。请注意当不带参数调用 legend() 时,标签以下划线开头的艺术家将被忽略。如何添加标签?

enter image description here

插入图片的代码:

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

x = list(range(1,13))
n = 40
index = [item for item in x for i in range(n)]

np.random.seed(123)

df = pd.DataFrame({'A': np.random.normal(30, 2, len(index)),
                   'B': np.random.normal(10, 2, len(index))},
                   index=index)

red_diamond = dict(markerfacecolor='r', marker='D')
blue_dot = dict(markerfacecolor='b', marker='o')

plt.figure(figsize=[10,5])
ax = plt.gca()
ax1 = sns.boxplot( x=df.index, y=df['A'], width=0.5, color='red', \
    boxprops=dict(alpha=.5), flierprops=red_diamond, labels='A')
ax2 = sns.boxplot( x=df.index, y=df['B'], width=0.5, color='blue', \
    boxprops=dict(alpha=.5), flierprops=blue_dot, labels='B')
plt.ylabel('Something')
plt.legend(loc="center", fontsize=8, frameon=False)

plt.show()

以下方法通过 boxprops 设置标签,并使用 ax.artists 的一部分创建图例。 (请注意,问题代码的 axax1ax2 都指向同一个子图,因此这里仅使用 ax。)

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

x = np.arange(1, 13)
index = np.repeat(x, 40)
np.random.seed(123)
df = pd.DataFrame({'A': np.random.normal(30, 2, len(index)),
                   'B': np.random.normal(10, 2, len(index))},
                  index=index)
red_diamond = dict(markerfacecolor='r', marker='D')
blue_dot = dict(markerfacecolor='b', marker='o')

plt.figure(figsize=[10, 5])
ax = sns.boxplot(data=df, x=df.index, y='A', width=0.5, color='red',
                 boxprops=dict(alpha=.5, label='A'), flierprops=red_diamond)
sns.boxplot(data=df, x=df.index, y='B', width=0.5, color='blue',
            boxprops=dict(alpha=.5, label='B'), flierprops=blue_dot, ax=ax)
ax.set_ylabel('Something')

handles, labels = ax.get_legend_handles_labels()
handles = [h for h, lbl, prev in zip(handles, labels, [None] + labels) if lbl != prev]
ax.legend(handles=handles, loc="center", fontsize=8, frameon=False)

plt.show()

替代方法可以是:

  • pd.melt 数据帧为长格式,因此可以使用 hue;这里的一个问题是图例不会考虑 boxprops 中的 alpha;也不支持设置不同的传单
  • 从自定义句柄创建图例